package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.tbit.common.constant.*;
import com.tbit.common.entity.RefundLog;
import com.tbit.common.entity.TransationLog;
import com.tbit.common.entity.UserCapitalChange;
import com.tbit.uqbike.client.config.DelayPayQKBJSwitch;
import com.tbit.uqbike.client.constant.*;
import com.tbit.uqbike.client.dao.capital.RefundLogDao;
import com.tbit.uqbike.client.dao.capital.RideFeeLogDao;
import com.tbit.uqbike.client.dao.capital.RideLogDetailsDao;
import com.tbit.uqbike.client.dao.capital.TransationLogDao;
import com.tbit.uqbike.client.dao.core.*;
import com.tbit.uqbike.client.dao.log.*;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.pojo.dto.RefundMoneyReturnDTO;
import com.tbit.uqbike.client.pojo.newEntity.*;
import com.tbit.uqbike.client.remote.adapay.PaymentUtil;
import com.tbit.uqbike.client.remote.sms.ClzySmsAuthUtil;
import com.tbit.uqbike.client.remote.sms.apistore.ApiStoreMsgUtils;
import com.tbit.uqbike.client.service.*;
import com.tbit.uqbike.client.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @Author: chen
 * @Description:
 * @Date: 创建于 15:25 2021/9/2
 */
@Service
@Slf4j
public class AdaPayServiceImpl implements AdaPayService {

    @Autowired
    UserToAgentDao userToAgentDao;
    @Autowired
    TransationLogDao transationLogDao;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private WeixinPayService weixinPayService;
    @Autowired
    private UserService userService;
    @Autowired
    private ZfbPayConfigService zfbPayConfigService;
    @Autowired
    private AliConfigService aliConfigService;
    @Autowired
    private AdaPayLogService adaPayLogService;
    @Autowired
    private UserDivideService userDivideService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private UserAdaPayLogService userAdaPayLogService;
    @Autowired
    private MachineBorrowDao machineBorrowDao;
    @Autowired
    private RideFeeLogDao rideFeeLogDao;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private UserAdaPayMoneyService userAdaPayMoneyService;
    @Autowired
    private UserRefundLogDao userRefundLogDao;
    @Autowired
    private RechargeService rechargeService;
    @Autowired
    private AdapayRefundLogDao adapayRefundLogDao;
    @Autowired
    private PushMsgLogService pushMsgLogService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private MemberFeeDao memberFeeDao;
    @Autowired
    private RideCardDao rideCardDao;
    @Autowired
    private VipCardDao vipCardDao;
    @Autowired
    private AgentDepositVipDao agentDepositVipDao;
    @Autowired
    private CouponDao couponDao;
    @Autowired
    private RefundOpeLogDao refundOpeLogDao;
    @Autowired
    private RideRefundLogDao rideRefundLogDao;
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private SmsAuthConfigDao smsAuthConfigDao;


    @Autowired
    private UserMsgDao usermsgDao;
    @Autowired
    private UserMealLogDao userMealLogDao;
    @Autowired
    private CouponMealDao couponMealDao;
    @Autowired
    private RideLogDetailsDao rideLogDetailsDao;
    @Autowired
    private RefundLogDao refundLogDao;
    @Autowired
    private RefundOrderDao refundOrderDao;
    @Autowired
    private RefundAdapayRecordDao refundAdapayRecordDao;
    @Resource
    private UserAdaPayLogTempService userAdaPayLogTempService;
    @Resource
    private DelayPayQKBJSwitch delayPayQKBJSwitch;

//    public static void main(String[] args) {
//        List<UserAdaPayLog> userAdaPayLogs = new ArrayList<>();
//
//        /**[UserAdaPayLog{userNO='0', accountId=11994, brandId=267, bankNO='null', orderNO='T_G_GX_VIP_230222134649_440981',
//         * proportion=0.02, money=1, fee=0, paymentId='002112023022213465010474344468686204928',
//         * confirmId='002112023022213465010474344468686204928', remark='null', mainUser=null,
//         * buyOrderNO='T_G_GX_VIP_230222134649_440981', buyOrderType=4, refundMoney=0, refundTime=null, rechargeMoney=50, serviceFee=1,
//         * type=1, allRefundMoney=0, refundFee=0, refundServiceFee=0},
//         * UserAdaPayLog{userNO='uqbikeSubAccount_267_145_1670316325724', accountId=11994, brandId=267, bankNO='null',
//         * orderNO='T_G_GX_VIP_230222134649_440981', proportion=0.55, money=26, fee=0, paymentId='002112023022213465010474344468686204928',
//         * confirmId='002112023022213465010474344468686204928',  remark='null', mainUser=null, buyOrderNO='T_G_GX_VIP_230222134649_440981',
//         * buyOrderType=4, refundMoney=11, rechargeMoney=50, serviceFee=1,
//         * type=0, allRefundMoney=20, refundFee=0, refundServiceFee=0},
//         * UserAdaPayLog{userNO='uqbikeSubAccount_267_144_1670315342164', accountId=11994, brandId=267, bankNO='null',
//         * orderNO='T_G_GX_VIP_230222134649_440981', proportion=0.45, money=23, fee=0, paymentId='002112023022213465010474344468686204928',
//         * confirmId='002112023022213465010474344468686204928', remark='null', mainUser=null,
//         * buyOrderNO='T_G_GX_VIP_230222134649_440981', buyOrderType=4, refundMoney=9,  rechargeMoney=50, serviceFee=1, type=0,
//         * allRefundMoney=20, refundFee=0, refundServiceFee=0}]
//         *
//         */
//
//   /* String json1 ="{userNO='0', accountId=100756, brandId=100751, bankNO='null', orderNO='GXBIKE20230122142726978184',\n"
//        + "       proportion=1.0, money=588, fee=0, paymentId='002112023012214272610463120662880894976', \n"
//        + "       confirmId='002112023012214272610463120662880894976', remark='null', \n"
//        + "       mainUser=null, buyOrderNO='202301222340221581', buyOrderType=3, refundMoney=0, refundTime=null, rechargeMoney=590, \n"
//        + "       serviceFee=0, type=0, allRefundMoney=0, refundFee=0, refundServiceFee=0}";
//
//    json1= json1.replaceAll("=",":");
//    UserAdaPayLog userAdaPayLog = JSON.parseObject(json1,UserAdaPayLog.class);
//
//    String json2 ="{userNO='0', accountId=100756, brandId=100751, bankNO='null', orderNO='GXBIKECASH1674368854371944870',\n"
//        + "       proportion=1.0, money=500, fee=2, paymentId='002112023012213593310463113648041672704',\n"
//        + "      confirmId='0021120230122142734990463120696120799232', remark='null',\n"
//        + "       mainUser=null, buyOrderNO='202301222340221581', buyOrderType=0, refundMoney=0, refundTime=null,\n"
//        + "      rechargeMoney=500, serviceFee=0, type=0, allRefundMoney=0, refundFee=0, refundServiceFee=0}";
//    json2= json2.replaceAll("=",":");
//    UserAdaPayLog userAdaPayLog2= JSON.parseObject(json2,UserAdaPayLog.class);
//    userAdaPayLogs.add(userAdaPayLog);
//    userAdaPayLogs.add(userAdaPayLog2);*/
//
//   /* String json1 ="{userNO='uqbikeSubAccount_11129_112_1667464530639', accountId=11131, brandId=11129, bankNO='null',\n"
//        + "       orderNO='T_G_GX_PAY_230221232113_536913', proportion=0.55, money=880, fee=0, paymentId='002112023022123211310474126630305607680',\n"
//        + "       confirmId='002112023022123211310474126630305607680', remark='null',\n"
//        + "       mainUser=null, buyOrderNO='202302219919890098', buyOrderType=3, refundMoney=0, refundTime=null,\n"
//        + "       rechargeMoney=1600, serviceFee=0, type=0, allRefundMoney=0, refundFee=0, refundServiceFee=0}";
//
//    json1= json1.replaceAll("=",":");
//    UserAdaPayLog userAdaPayLog = JSON.parseObject(json1,UserAdaPayLog.class);
//
//    String json2 ="{userNO='uqbikeSubAccount_11129_111_1667464131564', accountId=11131, brandId=11129,\n"
//        + "       bankNO='null', orderNO='T_G_GX_PAY_230221232113_536913', proportion=0.45, money=720, fee=6,\n"
//        + "       paymentId='002112023022123211310474126630305607680', confirmId='002112023022123211310474126630305607680',\n"
//        + "        remark='null', mainUser=null, buyOrderNO='202302219919890098',\n"
//        + "       buyOrderType=3, refundMoney=0, refundTime=null, rechargeMoney=1600, serviceFee=0, type=0, allRefundMoney=0,\n"
//        + "       refundFee=0, refundServiceFee=0}";
//    json2= json2.replaceAll("=",":");
//    UserAdaPayLog userAdaPayLog2= JSON.parseObject(json2,UserAdaPayLog.class);
//    userAdaPayLogs.add(userAdaPayLog);
//    userAdaPayLogs.add(userAdaPayLog2);*/
//
//        //
//        String json1 = "{userNO='uqbikeSubAccount_11129_111_1667464131564', accountId=11131, brandId=11129, bankNO='null'," +
//                " orderNO='T_G_GX_PAY_240201180108_732882', proportion=0.45, money=1305, fee=12, paymentId='002212024020118010810599069892424445952', " +
//                "confirmId='002212024020118010810599069892424445952', addTime='2023-01-02 00:00:00', remark='null', " +
//                "mainUser=null, buyOrderNO='T_G_GX_PAY_240201180108_732882'," +
//                " buyOrderType=0, refundMoney=0, refundTime=null, " +
//                "rechargeMoney=2900, serviceFee=0, type=0, allRefundMoney=0, refundFee=0, refundServiceFee=0}";
//
//        json1 = json1.replaceAll("=", ":");
//        UserAdaPayLog userAdaPayLog = JSON.parseObject(json1, UserAdaPayLog.class);
//
//        String json2 = "{userNO='uqbikeSubAccount_11129_112_1667464530639', accountId=11131, brandId=11129, bankNO='null', " +
//                "orderNO='T_G_GX_PAY_240201180108_732882', proportion=0.55, money=1595, fee=0, paymentId='002212024020118010810599069892424445952'," +
//                " confirmId='002212024020118010810599069892424445952', addTime='2023-01-02 00:00:00', remark='null', mainUser=null," +
//                " buyOrderNO='T_G_GX_PAY_240201180108_732882', buyOrderType=0, refundMoney=0, refundTime=null, rechargeMoney=2900, serviceFee=0, " +
//                "type=0, allRefundMoney=0, refundFee=0, refundServiceFee=0}";
//        json2 = json2.replaceAll("=", ":");
//        UserAdaPayLog userAdaPayLog2 = JSON.parseObject(json2, UserAdaPayLog.class);
//        userAdaPayLogs.add(userAdaPayLog);
//        userAdaPayLogs.add(userAdaPayLog2);
//
//       /* String json3 = "{userNO='uqbikeSubAccount_267_144_1670315342164', accountId=11994, brandId=267, bankNO='null', \n"
//                + "      orderNO='T_G_GX_VIP_230222134649_440981', proportion=0.45, money=23, fee=0, paymentId='002112023022213465010474344468686204928',\n"
//                + "      confirmId='002112023022213465010474344468686204928', remark='null', mainUser=null, \n"
//                + "      buyOrderNO='T_G_GX_VIP_230222134649_440981', buyOrderType=4, refundMoney=23,  rechargeMoney=50, serviceFee=1, type=0,\n"
//                + "      allRefundMoney=49, refundFee=0, refundServiceFee=0}";
//        json3 = json3.replaceAll("=", ":");
//        UserAdaPayLog userAdaPayLog3 = JSON.parseObject(json3, UserAdaPayLog.class);
//        userAdaPayLogs.add(userAdaPayLog3);*/
///*    UserAdaPayLog userAdaPayLog = new UserAdaPayLog();
//    userAdaPayLog.setUserNO("0");
//    userAdaPayLog.setAccountId(11113);
//    userAdaPayLog.setBrandId(0);
//    userAdaPayLog.setBankNO(null);
//    userAdaPayLog.setOrderNO("GXBIKECASH1655436803748328998");
//    userAdaPayLog.setProportion(0.16);
//    userAdaPayLog.setMoney(80);
//    userAdaPayLog.setFee(0);
//    userAdaPayLog.setPaymentId("002112022061514450410383037381143445504");
//    userAdaPayLog.setConfirmId("0021120220617113323990383713920817213440");
//    userAdaPayLog.setMainUser(null);
//    userAdaPayLog.setBuyOrderNO("0");
//    userAdaPayLog.setBuyOrderType(null);
//    userAdaPayLog.setRefundMoney(0);
//    userAdaPayLog.setRefundTime(null);
//    userAdaPayLog.setRechargeMoney(0);
//    userAdaPayLog.setServiceFee(0);
//    userAdaPayLog.setType(0);
//    userAdaPayLog.setAllRefundMoney(0);
//    userAdaPayLog.setRefundFee(0);
//    userAdaPayLog.setRefundServiceFee(0);
//    userAdaPayLogs.add(userAdaPayLog);
//    *//* *  UserAdaPayLog{userNO='lzx', accountId=11113, brandId=0, bankNO='null', orderNO='GXBIKECASH1655436803748328998',
//         *  proportion=0.84, money=420, fee=2, paymentId='002112022061514450410383037381143445504',
//         *  confirmId='0021120220617113323990383713920817213440', addTime=Fri Jun 17 11:33:24 CST 2022, remark='null',
//         *  mainUser=null, buyOrderNO='0', buyOrderType=null, refundMoney=0, refundTime=null, rechargeMoney=0,
//         *  serviceFee=0, type=0, allRefundMoney=0, refundFee=0, refundServiceFee=0}]*//*
//    UserAdaPayLog userAdaPayLog1 = new UserAdaPayLog();
//    userAdaPayLog1.setUserNO("lzx");
//    userAdaPayLog1.setAccountId(11113);
//    userAdaPayLog1.setBrandId(0);
//    userAdaPayLog1.setBankNO(null);
//    userAdaPayLog1.setOrderNO("GXBIKECASH1655436803748328998");
//    userAdaPayLog1.setProportion(0.84);
//    userAdaPayLog1.setMoney(420);
//    userAdaPayLog1.setFee(2);
//    userAdaPayLog1.setPaymentId("002112022061514450410383037381143445504");
//    userAdaPayLog1.setConfirmId("0021120220617113323990383713920817213440");
//    userAdaPayLog1.setMainUser(null);
//    userAdaPayLog1.setBuyOrderNO("0");
//    userAdaPayLog1.setBuyOrderType(null);
//    userAdaPayLog1.setRefundMoney(0);
//    userAdaPayLog1.setRefundTime(null);
//    userAdaPayLog1.setRechargeMoney(0);
//    userAdaPayLog1.setServiceFee(0);
//    userAdaPayLog1.setType(0);
//    userAdaPayLog1.setAllRefundMoney(0);
//    userAdaPayLog1.setRefundFee(0);
//    userAdaPayLog1.setRefundServiceFee(0);
//    userAdaPayLogs.add(userAdaPayLog1);*/
//        AdaPayServiceImpl adaPayService = new AdaPayServiceImpl();
//        System.out.println(adaPayService.getRefundDivMember(userAdaPayLogs, 1100D, 1));
//    }

    @Override
    public Map<String, Object> createOrder_wx_xcx(User user, Double money, String code, String remark, Boolean deposit,
                                                  Integer adAccountId, Integer rechargeType) {

        Map<String, Object> payment = null;
        // String orderNO= WeixinPayUtil.getNonceStr(deposit);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_pay);
        if (deposit) {
            orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_deposit);
        }
        WeixinPayConfig weixinPayConfig = weixinPayService.checkWxPay(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_XCX, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_WXXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Integer machineId = null;
        /**分账业务订单号*/
        String buyOrderNO = orderNO;
        /**充值结束订单默认区域id为订单未结束区域id*/
        if (rechargeType.equals(RechargeConstant.recharge_returnBike)) {
            Machine machine = machineBorrowDao.getRideByUserId(user.getUserId());
            if (machine != null) {
                adAccountId = machine.getAccountId();
            }
            RideLog rideLog = rideLogService.getByUserIdNotFinish(user.getUserId());
            if (rideLog != null) {
                buyOrderNO = rideLog.getOrderNO();
            }
            machineId = machine.getMachineId();
        }
        if (adAccountId == null) {
            adAccountId = user.getAccountId();
        }
        User userDB = userService.getByUserId(user.getUserId());
        adAccountId = checkAccountId(adAccountId, userDB);
        money = weixinPayService.order_base(user.getUserId(), money, remark, deposit, orderNO, adAccountId,
                RechargeConstant.RECHARGE_PAY_ADAPAY, rechargeType);
        if (deposit) {
            rechargeType = RechargeConstant.recharge_deposit;
        }
        //欠款补交单独记录类型
        if (userDB.getRideMoney() > 0) {
            rechargeType = RechargeConstant.recharge_QKBJ;
            RideLog notPayRideLog = rideLogService.findNOtPayByUserId(userDB.getUserId());
            // 欠款补交的 buyOrderNO 设为对应的骑行订单号
            if (notPayRideLog != null){
                // 有订单欠款补交 按 区域/车辆 分账
                buyOrderNO = notPayRideLog.getOrderNO();
                machineId = notPayRideLog.getMachineId();
                //欠款补交的区域id为当前骑行订单所在区域
                adAccountId = notPayRideLog.getAccountId();
            }else {
                // 无订单欠款补交 分到商户账号
                adAccountId = -1;
            }
        }
        payment = pay(adaPayConfig, money, orderNO, weixinPayConfig.getOpenId(), adAccountId, rechargeType, remark, buyOrderNO, machineId);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money, rechargeType,
                RechargeConstant.RECHARGE_PAY_ADAPAY, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    /**
     * 校验欠款补交区域id
     *
     * @param adAccountId 区域id
     * @param user        用户信息
     * @return
     */
    public Integer checkAccountId(Integer adAccountId, User user) {
        Boolean isLessMoney = false;
        if (user != null && user.getRideMoney() > 0) {
            isLessMoney = true;
        }
        if (isLessMoney) {
            RideLog rideLog = rideLogService.findLastByUserId(user.getUserId());
            if (rideLog != null) {
                adAccountId = rideLog.getAccountId();
            }
        }
        return adAccountId;
    }

    @Override
    public Map<String, Object> getMemberOrder_wx_xcx(String code, User user, Integer memberFeeId,
                                                     Integer adAccountId) {

        Map<String, Object> payment = null;
        /**订单编号*/
        // String orderNO = "GXBIKEDM"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_Mem);
        WeixinPayConfig weixinPayConfig = weixinPayService.checkWxPay(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_XCX, code);
        weixinPayService.checkIsByMem(user, adAccountId);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_WXXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getMemberOrder_base(RechargeConstant.RECHARGE_PAY_ADAPAY, user, adAccountId, orderNO, memberFeeId);
        payment = pay(adaPayConfig, money, orderNO, weixinPayConfig.getOpenId(), adAccountId,
                RechargeConstant.recharge_Mem, GoodsConstant.GOODS_NAME_MEMBERORDER, orderNO,null);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,openId,null, "delay");
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_Mem, RechargeConstant.RECHARGE_PAY_ADAPAY, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getRideCardOrder_wx_xcx(String code, User user, Integer rideCardId,
                                                       Integer adAccountId) {

        Map<String, Object> payment = null;

        /**订单编号*/
        //String orderNO = "GXBIKERC"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_rideCard);
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayService.checkWxPay(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_XCX, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_WXXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getRideCardOrder_base(RechargeConstant.RECHARGE_PAY_ADAPAY, user, rideCardId, orderNO, adAccountId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,openId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, weixinPayConfig.getOpenId(), adAccountId,
                RechargeConstant.recharge_rideCard, GoodsConstant.GOODS_NAME_RIDECARDORDER, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_rideCard, RechargeConstant.RECHARGE_PAY_ADAPAY, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getVipOrder_wx_xcx(String code, User user, Integer vipId, Integer adAccountId) {
        Map<String, Object> payment = null;

        /**订单编号*/
        // String orderNO = "UQBIKEVIP"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_vip);
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayService.checkWxPay(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_XCX, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_WXXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getVipOrder_base(RechargeConstant.RECHARGE_PAY_ADAPAY, user, vipId, orderNO, adAccountId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,openId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, weixinPayConfig.getOpenId(), adAccountId,
                RechargeConstant.recharge_vip, GoodsConstant.GOODS_NAME_VIPORDER, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_vip, RechargeConstant.RECHARGE_PAY_ADAPAY, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getMeal_wx_xcx(String code, User user, Integer mealId, Integer adAccountId) {
        Map<String, Object> payment = null;

        /**订单编号*/
        //String orderNO = "GXBIKEMEAL"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_meal);
        /**支付配置信息(1:微信APP支付；2：微信小程序支付)*/
        WeixinPayConfig weixinPayConfig = weixinPayService.checkWxPay(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_XCX, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_WXXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getMeal_base(RechargeConstant.RECHARGE_PAY_ADAPAY, user, mealId, orderNO, adAccountId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,openId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, weixinPayConfig.getOpenId(), adAccountId,
                RechargeConstant.recharge_meal, GoodsConstant.GOODS_NAME_MEAL, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_meal, RechargeConstant.RECHARGE_PAY_ADAPAY, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> createOrder_zfb_xcx(User user, Double money, String code,
                                                   String remark, Boolean deposit, Integer adAccountId, Integer rechargeType) {
        Map<String, Object> payment = null;

        //  String orderNO= WeixinPayUtil.getNonceStr(deposit);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_pay);
        if (deposit) {
            orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_deposit);
        }
        String aliUserId = getAliUserId(user, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_ZFBXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        String buyOrderNO = orderNO;
        Integer machineId = null;
        /**充值结束订单默认区域id为订单未结束区域id*/
        if (rechargeType.equals(RechargeConstant.recharge_returnBike)) {
            Machine machine = machineBorrowDao.getRideByUserId(user.getUserId());
            if (machine != null) {
                adAccountId = machine.getAccountId();
            }
            RideLog rideLog = rideLogService.getByUserIdNotFinish(user.getUserId());
            if (rideLog != null) {
                buyOrderNO = rideLog.getOrderNO();
            }
            machineId = machine.getMachineId();
        }
        User userDB = userService.getByUserId(user.getUserId());
        adAccountId = checkAccountId(adAccountId, userDB);
        money = weixinPayService.order_base(user.getUserId(), money, remark, deposit, orderNO, adAccountId,
                RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, rechargeType);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,aliUserId,null, "delay");
        if (deposit) {
            rechargeType = RechargeConstant.recharge_deposit;
        }
        //欠款补交单独记录类型
        if (userDB.getRideMoney() > 0) {
            rechargeType = RechargeConstant.recharge_QKBJ;
            RideLog notPayRideLog = rideLogService.findNOtPayByUserId(userDB.getUserId());
            machineId = notPayRideLog.getMachineId();
            // 欠款补交的 buyOrderNO 设为对应的骑行订单号
            buyOrderNO = notPayRideLog.getOrderNO();
            //欠款补交的区域id为当前骑行订单所在区域
            adAccountId = notPayRideLog.getAccountId();
        }
        payment = pay(adaPayConfig, money, orderNO, aliUserId, adAccountId, rechargeType, remark, buyOrderNO, machineId);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money, rechargeType,
                RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getMemberOrder_zfb_xcx(String code, User user, Integer memberFeeId,
                                                      Integer adAccountId) {
        Map<String, Object> payment = null;

        /**订单编号*/
        // String orderNO = "GXBIKEDM"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_Mem);
        String aliUserId = getAliUserId(user, code);
        weixinPayService.checkIsByMem(user, adAccountId);

        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_ZFBXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getMemberOrder_base(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user, adAccountId, orderNO, memberFeeId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,aliUserId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, aliUserId, adAccountId, RechargeConstant.recharge_Mem, GoodsConstant.GOODS_NAME_MEMBERORDER, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_Mem, RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getRideCardOrder_zfb_xcx(String code, User user, Integer rideCardId,
                                                        Integer adAccountId) {
        Map<String, Object> payment = null;
        /**订单编号*/
        //String orderNO = "GXBIKERC"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_rideCard);
        String aliUserId = getAliUserId(user, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_ZFBXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getRideCardOrder_base(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user, rideCardId, orderNO, adAccountId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,aliUserId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, aliUserId, adAccountId, RechargeConstant.recharge_rideCard, GoodsConstant.GOODS_NAME_RIDECARDORDER, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_rideCard, RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getVipOrder_zfb_xcx(String code, User user, Integer vipId,
                                                   Integer adAccountId) {
        Map<String, Object> payment = null;
        /**订单编号*/
        //String orderNO = "UQBIKEVIP"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_vip);
        String aliUserId = getAliUserId(user, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_ZFBXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getVipOrder_base(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user, vipId, orderNO, adAccountId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,aliUserId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, aliUserId, adAccountId, RechargeConstant.recharge_vip, GoodsConstant.GOODS_NAME_VIPORDER, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_vip, RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    @Override
    public Map<String, Object> getMeal_zfb_xcx(String code, User user, Integer mealId,
                                               Integer adAccountId) {
        Map<String, Object> payment = null;
        /**订单编号*/
        //String orderNO = "GXBIKEMEAL"+ DateTimeUtil.getDaformatyyyyMMddHHmmss(new Date()) + TenpayUtil.buildRandom(6);
        String orderNO = OrderNoUtil.getOrderNO((long) TenpayUtil.buildRandom(6), RechargeConstant.recharge_meal);
        String aliUserId = getAliUserId(user, code);
        AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_ZFBXCX);
        if (adaPayConfig == null) {
            throw new BaseException("-4005", "聚合支付未配置信息");
        }
        Double money = weixinPayService.getMeal_base(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user, mealId, orderNO, adAccountId);
        //payment=PaymentUtil.executePayment(adaPayConfig,money,orderNO,aliUserId,null, "delay");
        payment = pay(adaPayConfig, money, orderNO, aliUserId, adAccountId, RechargeConstant.recharge_meal, GoodsConstant.GOODS_NAME_MEAL, orderNO,null);
        /**添加分账日志*/
        addAdaPayLog(adaPayConfig.getModel(), orderNO, adAccountId, user.getUserId(), money,
                RechargeConstant.recharge_meal, RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB, user.getAccountId());
        /**支付信息推送mq队列*/
        weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_CREATE,null);
        return payment;
    }

    /***
     * 获取支付宝用户id
     * @param user
     * @param code
     * @return
     */
    public String getAliUserId(User user, String code) {
        /**支付配置信息*/
        ZfbPayConfig zfbPayConfig = zfbPayConfigService.getByAccountId(user.getAccountId(),
                RechargeConstant.ZFB_PAY_XCX);
        if (zfbPayConfig == null) {
            throw new BaseException("-2009", "该品牌支付宝未配置");
        }

        /**获取支付宝*/
        String aliUserId = SystemData.aliPayMap.get(user.getUserId());
        if (aliUserId == null) {
            AlipaySystemOauthTokenResponse reponse = aliConfigService.alipaySystemOauthToken(user.getAccountId(), code, zfbPayConfig);
            aliUserId = reponse.getUserId();
        }
        if (aliUserId == null) {
            throw new BaseException("-4006", "获取支付宝用户id失败");
        }
        return aliUserId;
    }

    @Override
    public void delay(Double money, User user, Integer adAccountId, String orderNO, Integer rideMoney) {
        RideLog rideLog = rideLogService.getByOrderNO(orderNO);
        if (rideLog == null) {
            log.info("骑行订单不存在，分账结束" + orderNO);
            return;
        }
        /**用户余额变动,默认全部都是微信、支付宝余额支付*/
        RideFeeLog rideFeeLog = new RideFeeLog();
        rideFeeLog.setMoney(rideMoney);
        rideFeeLog.setRealMoney(0);
        rideFeeLog.setOverMoney(rideMoney);


        /**需要扣除的金额大于0*/
        if (money > 0) {
            AdaPayConfig adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_WXXCX);
            if (adaPayConfig == null) {
                adaPayConfig = cacheService.getAdaPayConfig(user.getAccountId(), AdaPayConstant.PAY_CHANNEL_ZFBXCX);
            }
            if (adaPayConfig == null) {
                addRideFeeLog(orderNO, adAccountId, user, rideMoney, 0, RechargeConstant.recharge_returnBike);
                return;
            }
            /**如果开启全额分账,所有的订单已经分账,不再触发延时分账*/
            Boolean cashAll = getPayType(adaPayConfig.getAccountId());
            if (cashAll) {
                return;
            }

            Integer machineId = rideLog.getMachineId();
//            List<UserDivide> divides = userDivideService.getByAccountId(adAccountId);
            List<UserDivide> divides = userDivideService.getAreaOrMachineDivide(adAccountId,machineId);
            Map<String, UserDivide> userMap = new HashMap<>();
            for (UserDivide userDivide : divides) {
                userMap.put(userDivide.getUserNO(), userDivide);
            }

            List<AdaPayLog> adaPayLogs = adaPayLogService.getByUserId(user.getUserId());
            if (adaPayLogs.size() > 0) {
                /**兼容服务费扣取到服务费账户*/
                UserDivide userDivide = getHandelFee(adaPayConfig.getAccountId());
                if (userDivide != null) {
                    userMap.put(userDivide.getUserNO(), userDivide);
                }
                /**是否发起了分账订单*/
                boolean isCash = false;
                Integer realMoney = 0;
                for (AdaPayLog adaPayLog : adaPayLogs) {
                    if (adaPayConfig == null) {
                        break;
                    }
                    //充值不在区域内的数据分账也要分到对应区域
                    adaPayLog.setAccountId(adAccountId);
                    /**可分账金额=订单金额-已分账金额-已退款金额*/
                    Double canCashMoney = adaPayLog.getMoney() - adaPayLog.getCashMoney() - adaPayLog.getRefundMoney();
                    if (canCashMoney <= 0) {
                        continue;
                    }
                    if (money >= canCashMoney) {
                        /**订单全额分账*/
                        List<DivMembers> list = AdapayUtil.getCashUser(divides, canCashMoney, userDivide);
                        Boolean result = cash(adaPayConfig, canCashMoney, adaPayLog, AdaPayConstant.ADAPAY_LOG_CASH, list, userMap, orderNO, userDivide, rideLog.getMoney());
                        if (result) {
                            realMoney = realMoney + canCashMoney.intValue();
                            money = money - canCashMoney;
                        }
                    } else {
                        /**订单部分分账*/
                        List<DivMembers> list = AdapayUtil.getCashUser(divides, money, userDivide);
                        Boolean result = cash(adaPayConfig, money, adaPayLog, AdaPayConstant.ADAPAY_LOG_PAY, list, userMap, orderNO, userDivide, rideLog.getMoney());
                        if (result) {
                            realMoney = realMoney + money.intValue();
                            money = 0D;
                        }
                    }
                    isCash = true;
                    /**分账金额为0，退出本次分账*/
                    if (money <= 0) {
                        break;
                    }
                }
                /**延时分账，更新分账时间*/
                if (isCash) {
                    //支付时间为空时才更新
                    if (rideLog.getPayTime() == null) {
                        RideLog rideLogDB = new RideLog();
                        rideLogDB.setPayTime(DateTimeUtil.getNowTime());
                        rideLogDB.setOrderNO(rideLog.getOrderNO());
                        rideLogService.updateByOrderNOSelective(rideLogDB);
                    }
                    rideFeeLog = addRideFeeLog(orderNO, adAccountId, user, rideMoney, realMoney,
                            RechargeConstant.recharge_returnBike);
                }
                if (money > 0) {
                    log.warn("未找到部分充值订单" + user.getUserId() + ",金额=" + money);
                }
            } else {
                /**记录订单扣费记录*/
                rideFeeLog = addRideFeeLog(orderNO, adAccountId, user, rideMoney, 0,
                        RechargeConstant.recharge_returnBike);
                log.warn("未找到充值订单" + user.getUserId() + ",金额=" + money);
            }

        }
        /**更新用户金额变动*/
        userAdaPayMoneyService.add(user, -rideFeeLog.getOverMoney().intValue(), -rideFeeLog.getRealMoney().intValue());
    }

    @Override
    public void checkIsAdaPay(Integer accountId) {
        BrandRemoteConfig brandRemoteConfig = cacheService.getBrandRemoteConfig(accountId,
                BrandConstant.ADAPAY_BUTTON);
        if (brandRemoteConfig == null) {
            return;
        }
        Integer button = Integer.valueOf(brandRemoteConfig.getParamKV().substring(brandRemoteConfig.getParamKV().indexOf("=") + 1));
        /**聚合支付限制*/
        if (button != 0) {
            throw new BaseException("-101", "网络异常");
        }
    }

    /**
     * 卡券失效
     *
     * @param recharge
     */
    private void invalidCard(Recharge recharge) {
        Integer rechargeType = recharge.getRechargeType();
        String orderNO = recharge.getOrderNO();
        Integer userId = recharge.getUserId();
        if (rechargeType == null) {
            return;
        }
        if (rechargeType.equals(RechargeConstant.recharge_Mem)) {
            log.info("============免押卡退款========");
            Map<String, Object> map = memberFeeDao.selectByOrderNO(orderNO);
            Integer accountId = (Integer) map.get("accountId");
            Integer type = (Integer) map.get("type");
            int count = memberFeeDao.countValid(accountId, userId);
            count = count == 1 ? 1 : 0;
            //修改该订单卡到期时间为今天过期
            int i = memberFeeDao.updateExpireTime(orderNO);
            /*修改用户区域免押到期时间*/
            agentDepositVipDao.updateExpire(accountId, userId, type);
            /*兼容免押卡多出购买的时间*/
            if (count == 1) {
                agentDepositVipDao.updateExpire(accountId, userId, 0);
            } else {
                //兼容购买多张免押卡，卡上到期时间正确
                memberFeeDao.updateExpireTimes((String) map.get("expireTime"), accountId, userId, type);
            }

        }
        //骑行卡退款
        if (rechargeType.equals(RechargeConstant.recharge_rideCard)) {
            log.info("============骑行卡退款========");
            UserMember userMember = new UserMember(orderNO);
            int i = rideCardDao.updateValid(userMember);

        }
        //会员卡退款
        if (rechargeType.equals(RechargeConstant.recharge_vip)) {
            log.info("============会员卡退款========");
            int i = vipCardDao.updateValid(orderNO);
        }
        /**优惠券套餐退款*/
        if (rechargeType.equals(RechargeConstant.recharge_meal)) {
            log.info("============优惠券套餐退款========");
            UserMealLog userMealLog = userMealLogDao.getByOrderNO(recharge.getOrderNO());
            if (userMealLog == null) {
                return;
            }
            CouponMeal couponMeal = couponMealDao.getByMealId(userMealLog.getMealId());
            if (couponMeal == null) {
                return;
            }
            couponDao.userCouponEdit(couponMeal.getCouponId(), userId, recharge.getOrderNO());
        }

    }

    private Double refundHandler(Double money, Integer userId, String buyOrderNO, AdaPayConfig adaPayConfig, Integer adAccountId,
                                 Integer operatorId, String operatorName, String operatorPhone, String remark, boolean isFine,
                                 RideLog rideLog, String transactionLogRemark) {
        User user = userService.getByUserId(userId);
        if (user == null) {
            log.warn("用户不存在");
            return 0d;
        }
        Double refundMoney = 0D;
        Double allAdaPayMoney = 0D;
        Double otherMoney = 0D;
        boolean isAdaPay = false;
        /**业务订单号不为空，代表是退还骑行卡或会员卡或免押卡、或优惠券套餐或骑行订单*/
        String rideOrderNo = null;
        //String businessNO = OrderNoUtil.getRefundNO();
        if (rideLog != null) {
            adAccountId = rideLog.getAccountId();
            rideOrderNo = rideLog.getOrderNO();
        }
        /**退款类型*/
        Integer changeType = null;
        if (rideLog != null) {
            changeType = RefundLogContent.rideLog_Refund;
        }
        if (isFine) {
            changeType = RefundLogContent.userFine_Refund;
        }
        List<UserAdaPayLog> userAdaPayLogs = userAdaPayLogService.getBuBuyOrderNO(buyOrderNO);

        Account account = accountService.getByAccountId(adAccountId);

        if (userAdaPayLogs.size() > 0) {
            isAdaPay = true;
        }
        /**骑行订单退款，需要查询多少是汇付订单多少是微信订单*/
        /**可分账订单金额*/
        Double adaPayMoney = 0D;
        for (UserAdaPayLog u : userAdaPayLogs) {
            adAccountId = u.getAccountId();
            adaPayMoney = adaPayMoney + u.getMoney() - u.getRefundMoney();
        }
        /**用户非聚合支付金额*/
        Double notAdaPayMoney = money - adaPayMoney;
        List<String> merchantNOList = new ArrayList<>();
        Recharge rechargeDB = rechargeService.getByOrderNO(buyOrderNO);
        log.info("单号{}申请退款金额{}，是否汇付金额{}，汇付金额为{}",buyOrderNO,money,isAdaPay,adaPayMoney);
        if (isAdaPay) {
            /**
             * 如果是汇付退款时需要处理分账的逻辑
             */
            if (adaPayMoney > money) {
                /**汇付退款*/
                refundMoney = handelRefund(account, userAdaPayLogs, money, adaPayConfig, user, false, buyOrderNO, buyOrderNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, null);
            } else {
                /**汇付退款*/
                refundMoney = handelRefund(account, userAdaPayLogs, adaPayMoney, adaPayConfig, user, false, buyOrderNO, buyOrderNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, null);
            }
            allAdaPayMoney = refundMoney;
            /**使卡券失效*/
            if (rechargeDB != null) {
                invalidCard(rechargeDB);
            }

        }
        DateTime time = new DateTime();
        log.info(buyOrderNO + "骑行订单退款,汇付金额=" + adaPayMoney + ",其他=" + notAdaPayMoney);
        /**订单是包含BIKE开头，代表是骑行卡或会员卡或免押卡、或优惠券套餐*/
        if (notAdaPayMoney > 0) {
            /**如果是骑行卡或会员卡或免押卡、或优惠券套餐，只退之前充值那一笔订单*/
            if (rechargeDB != null) {
                log.info("单号{}进行卡券退款,非汇付退款金额{}",buyOrderNO,notAdaPayMoney);
                /**生成退款订单号*/
                String refundNO = OrderNoUtil.getRefundNO();
                Double realRefundMoney = userService.getReturnResult(account, rechargeDB, refundNO, notAdaPayMoney, user, buyOrderNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark);
                if (realRefundMoney > 0) {
                    refundMoney = realRefundMoney;
                    addRefundLog(rechargeDB, adAccountId, refundNO, refundMoney, userId, buyOrderNO);
                    otherMoney = otherMoney + refundMoney;

                    /**添加退款记录*/
                    RideFeeLog rideFeeLog = new RideFeeLog();
                    rideFeeLog.setOrderNO(buyOrderNO);
                    rideFeeLog.setRefundMoney(refundMoney.intValue());
                    rideFeeLog.setRefundRealMoney(allAdaPayMoney.intValue());
                    rideFeeLog.setRefundOverMoney(otherMoney.intValue());
                    rideFeeLogDao.editRefund(rideFeeLog);

                    /** 推送退款日志 */
                    merchantNOList.add(rechargeDB.getOrderNO());

                    pushRefundLog(user, account, realRefundMoney, buyOrderNO, merchantNOList, rechargeDB,
                            changeType, rideOrderNo, operatorId, operatorName, operatorPhone, remark,time);
                    /**使卡券失效*/
                    invalidCard(rechargeDB);

                }

                return refundMoney;
            }
            log.info("单号{}进行骑行订单退款，非汇付金额{}",buyOrderNO,notAdaPayMoney);
            /**用户骑行订单存在微信余额，需要退还微信等其他支付方式余额*/
            List<Recharge> recharges = rechargeService.getByUserIdAndType(userId, rideLog.getPayTime());
            recharges = userService.getCanRefundOrder(userId, recharges);
            if (recharges != null) {
                for (Recharge recharge : recharges) {
                    /**生成退款订单号*/
                    String refundNO = OrderNoUtil.getRefundNO();
                    Double realRefundMoney = 0d;
                    if (recharge.getCanRefundMoney() >= notAdaPayMoney) {
                        realRefundMoney = userService.getReturnResult(account, recharge, refundNO, notAdaPayMoney, user, buyOrderNO, operatorId,
                                operatorName, operatorPhone, rideOrderNo, transactionLogRemark);
                        if (realRefundMoney > 0) {
                            refundMoney = refundMoney + realRefundMoney;
                            otherMoney = otherMoney + realRefundMoney;
                            addRefundLog(recharge, adAccountId, refundNO, realRefundMoney, userId, buyOrderNO);
                            rechargeDB = recharge;
                            break;
                        }
                    } else {
                        realRefundMoney = userService.getReturnResult(account, recharge, refundNO, recharge.getCanRefundMoney(), user, buyOrderNO,
                                operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark);
                        if (realRefundMoney > 0) {
                            refundMoney = refundMoney + realRefundMoney;
                            otherMoney = otherMoney + realRefundMoney;
                            notAdaPayMoney = notAdaPayMoney - realRefundMoney;
                            addRefundLog(recharge, adAccountId, refundNO, realRefundMoney, userId, buyOrderNO);
                            rechargeDB = recharge;
                        }
                    }
                    /** 推送退款日志 */
                    merchantNOList.add(recharge.getOrderNO());
                }
            }
        }
        if (refundMoney > 0) {
            /**添加退款记录*/
            RideFeeLog rideFeeLog = new RideFeeLog();
            rideFeeLog.setOrderNO(buyOrderNO);
            rideFeeLog.setRefundMoney(refundMoney.intValue());
            rideFeeLog.setRefundRealMoney(allAdaPayMoney.intValue());
            rideFeeLog.setRefundOverMoney(otherMoney.intValue());
            rideFeeLogDao.editRefund(rideFeeLog);


            /** 推送退款日志 */

            pushRefundLog(user, account, refundMoney, buyOrderNO, merchantNOList, rechargeDB,
                    changeType, rideOrderNo, operatorId, operatorName, operatorPhone, remark, time);
        }
        return refundMoney;
    }

    private Map<String, Object> refundHandlerNew(Double money, Integer userId, String buyOrderNO, AdaPayConfig adaPayConfig, Integer adAccountId,
                                                 Integer operatorId, String operatorName, String operatorPhone, String remark, boolean isFine,
                                                 RideLog rideLog, String transactionLogRemark, Integer sendMsg, boolean isApi, String refundBatch) {
        Map<String, Object> resMap = new HashMap<>();
        User user = userService.getByUserId(userId);
        if (user == null) {
            log.warn("用户不存在");
            resMap.put(RefundConstant.REFUNDMONEY, 0);
            resMap.put(RefundConstant.REFUNDNO, "0000");
            return resMap;
        }
        Double refundMoney = 0D;
        Double allAdaPayMoney = 0D;
        Double otherMoney = 0D;
        boolean isAdaPay = false;
        /**业务订单号不为空，代表是退还骑行卡或会员卡或免押卡、或优惠券套餐或骑行订单*/
        String rideOrderNo = null;
        //String businessNO = OrderNoUtil.getRefundNO();
        if (rideLog != null) {
            adAccountId = rideLog.getAccountId();
            rideOrderNo = rideLog.getOrderNO();
        }
        /**退款类型*/
        Integer changeType = null;
        if (rideLog != null) {
            changeType = RefundLogContent.rideLog_Refund;
        }
        if (isFine) {
            changeType = RefundLogContent.userFine_Refund;
        }
        List<UserAdaPayLog> userAdaPayLogs = userAdaPayLogService.getBuBuyOrderNO(buyOrderNO);
        log.info("用户={}，用户分账日志userAdaPayLogs={}", userId, JSON.toJSONString(userAdaPayLogs));
        Account account = accountService.getByAccountId(adAccountId);
        if (userAdaPayLogs.size() > 0) {
            isAdaPay = true;
        }
        /**骑行订单退款，需要查询多少是汇付订单多少是微信订单*/
        /**可分账订单金额*/
        Double adaPayMoney = 0D;
        for (UserAdaPayLog u : userAdaPayLogs) {
            adAccountId = u.getAccountId();
            adaPayMoney = adaPayMoney + u.getMoney() - u.getRefundMoney();
        }
        log.info("订单号={}，退款输入金额={}，汇付金额={}", buyOrderNO, money, adaPayMoney);
        /**用户非聚合支付金额*/
        Double notAdaPayMoney = money - adaPayMoney;
        List<String> merchantNOList = new ArrayList<>();
        // 余额，优惠券，会员卡，骑行套餐 会存在recharge中
        Recharge rechargeDB = rechargeService.getByOrderNO(buyOrderNO);
        log.info("用户充值订单rechargeDB={}", JSON.toJSONString(rechargeDB));
        String refundNO = null;
        if (isAdaPay) {
            log.info("订单号={}，adaPayMoney={}", buyOrderNO, adaPayMoney);
            if (adaPayMoney > money) {
                /**汇付退款*/
                resMap = handelRefundNew(account, userAdaPayLogs, money, adaPayConfig, user, false, buyOrderNO, buyOrderNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, null, sendMsg, isApi, refundBatch);
            } else {
                /**汇付退款*/
                resMap = handelRefundNew(account, userAdaPayLogs, adaPayMoney, adaPayConfig, user, false, buyOrderNO, buyOrderNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, null, sendMsg, isApi, refundBatch);
            }
            refundMoney = (Double) resMap.getOrDefault(RefundConstant.REFUNDMONEY, 0d);
            allAdaPayMoney = refundMoney;
//            /**使卡券失效*/
//            if (rechargeDB != null) {
//                log.info("使卡券失效");
//                invalidCard(rechargeDB);
//            }
            refundNO = (String) resMap.getOrDefault(RefundConstant.REFUNDNO, "0000");
        }

        log.info(buyOrderNO + "骑行订单/卡券退款,汇付金额=" + adaPayMoney + ",其他=" + notAdaPayMoney);
        /**订单是包含BIKE开头，代表是骑行卡或会员卡或免押卡、或优惠券套餐*/
        if (notAdaPayMoney > 0) {
            /**如果是骑行卡或会员卡或免押卡、或优惠券套餐，只退之前充值那一笔订单*/
            if (rechargeDB != null) {   // 代表不是骑行订单（骑行订单传递的骑行单号在recharge中查不到）
                /**生成退款订单号*/
                refundNO = OrderNoUtil.getRefundNO();
                log.info("骑行订单退款进入rechargeDB != null，退款订单号={}", refundNO);
                Double realRefundMoney = userService.getReturnResultNew(account, rechargeDB, refundNO, notAdaPayMoney, user, buyOrderNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, sendMsg, isApi, refundBatch);

                if (realRefundMoney > 0) {
                    refundMoney = realRefundMoney;
                    otherMoney = otherMoney + refundMoney;
                    resMap.put(RefundConstant.REFUNDMONEY, refundMoney);
                    resMap.put(RefundConstant.REFUNDNO, refundNO);

//                    invalidCard(rechargeDB);

                    RefundOrder refundOrder = refundOrderDao.getByRefundNO(refundNO);
                    if (Objects.isNull(refundOrder)) {
                        log.error("refundorder为空，请排查refundorder插入问题,refundNO={}", refundNO);
                        return resMap;
                    }

                    String logTag = Objects.isNull(refundOrder.getLogTag()) ? (RefundConstant.APILOG2 + ",") : (refundOrder.getLogTag() + RefundConstant.APILOG2 + ",");
                    refundOrder.setLogTag(logTag);
                    refundOrder.setAdAccountId(adAccountId);
                    refundOrder.setAllAdaPayMoney(allAdaPayMoney);
                    refundOrder.setOtherMoney(otherMoney);
                    refundOrder.setChangeType(changeType);
                    refundOrder.setRideOrderNO(rideOrderNo);
                    refundOrder.setOperatorId(operatorId);
                    refundOrder.setOperatorName(operatorName);
                    refundOrder.setOperatorPhone(operatorPhone);
                    refundOrder.setRemark(remark);
                    refundOrderDao.update(refundOrder);
                }
                return resMap;
            }
            /**用户骑行订单存在微信余额，需要退还微信等其他支付方式余额 ---- 这种是在骑行订单中存在余额*/
            List<Recharge> recharges = rechargeService.getByUserIdAndType(userId, rideLog.getPayTime());
            recharges = userService.getCanRefundOrder(userId, recharges);
            log.info("用户可退充值订单列表={}", JSON.toJSONString(recharges));
            if (recharges != null) {
                for (Recharge recharge : recharges) {
                    /**生成退款订单号*/
                    refundNO = OrderNoUtil.getRefundNO();
                    log.info("退款订单号={}", refundNO);
                    Double realRefundMoney = 0d;
                    if (recharge.getCanRefundMoney() >= notAdaPayMoney) {
                        log.info("分支recharge.getCanRefundMoney() >= notAdaPayMoney");
                        realRefundMoney = userService.getReturnResultNew(account, recharge, refundNO, notAdaPayMoney, user, buyOrderNO, operatorId,
                                operatorName, operatorPhone, rideOrderNo, transactionLogRemark, sendMsg, isApi, refundBatch);

                        if (realRefundMoney > 0) {
                            refundMoney = refundMoney + realRefundMoney;
                            otherMoney = otherMoney + realRefundMoney;
                            rechargeDB = recharge;

                            resMap.put(RefundConstant.REFUNDMONEY, refundMoney);
                            resMap.put(RefundConstant.REFUNDNO, refundNO);

                            RefundOrder refundOrder = refundOrderDao.getByRefundNO(refundNO);
                            if (Objects.isNull(refundOrder)) {
                                log.error("refundorder为空，请排查refundorder插入问题,refundNO={}", refundNO);
                                return resMap;
                            }
                            String logTag = Objects.isNull(refundOrder.getLogTag()) ? (RefundConstant.APILOG4 + ",") : (refundOrder.getLogTag() + RefundConstant.APILOG4 + ",");
                            refundOrder.setLogTag(logTag);
                            refundOrder.setAdAccountId(adAccountId);
                            refundOrderDao.update(refundOrder);

                            break;
                        }
                    } else {
                        log.info("分支recharge.getCanRefundMoney() < notAdaPayMoney");
                        realRefundMoney = userService.getReturnResultNew(account, recharge, refundNO, recharge.getCanRefundMoney(), user, buyOrderNO,
                                operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, sendMsg, isApi, refundBatch);
                        if (realRefundMoney > 0) {
                            refundMoney = refundMoney + realRefundMoney;
                            otherMoney = otherMoney + realRefundMoney;
                            notAdaPayMoney = notAdaPayMoney - realRefundMoney;
                            rechargeDB = recharge;

                            resMap.put(RefundConstant.REFUNDMONEY, refundMoney);
                            resMap.put(RefundConstant.REFUNDNO, refundNO);

                            RefundOrder refundOrder = refundOrderDao.getByRefundNO(refundNO);
                            if (Objects.isNull(refundOrder)) {
                                log.error("refundorder为空，请排查refundorder插入问题,refundNO={}", refundNO);
                                return resMap;
                            }
                            String logTag = Objects.isNull(refundOrder.getLogTag()) ? (RefundConstant.APILOG4 + ",") : (refundOrder.getLogTag() + RefundConstant.APILOG4 + ",");
                            refundOrder.setLogTag(logTag);
                            refundOrder.setAdAccountId(adAccountId);
                            refundOrderDao.update(refundOrder);
                        }
                    }
                    /** 推送退款日志 */
                    merchantNOList.add(recharge.getOrderNO());
                }
            }
        }
        if (refundMoney > 0) {
            refundNO = (refundNO == null) ? (String) resMap.get(RefundConstant.REFUNDNO) : refundNO;
            RefundOrder refundOrder = refundOrderDao.getByRefundNO(refundNO);
            if (Objects.isNull(refundOrder)) {
                log.error("refundorder为空，请排查refundorder插入问题,refundNO={}", refundNO);
                return resMap;
            }
            String logTag = Objects.isNull(refundOrder.getLogTag()) ? (RefundConstant.APILOG3 + ",") : (refundOrder.getLogTag() + RefundConstant.APILOG3 + ",");
            refundOrder.setLogTag(logTag);

            //todo 变更字段，以免其他日志记录取条件时，被覆盖了
//            refundOrder.setRefundMoney(refundMoney);
//            refundOrder.setAlreadyRefundMoney(allAdaPayMoney);
            refundOrder.setFineOrRideOrCardAllRefundMoney(refundMoney);
            refundOrder.setFineOrRideOrCardAllAdapayRefundMoney(allAdaPayMoney);
            refundOrder.setOtherMoney(otherMoney);
            refundOrder.setChangeType(changeType);
            refundOrder.setAdAccountId(adAccountId);
            refundOrder.setMerchantNOListStr(JSON.toJSONString(merchantNOList));
            refundOrder.setChangeType(changeType);
            refundOrder.setRideOrderNO(rideOrderNo);
            refundOrder.setOperatorId(operatorId);
            refundOrder.setOperatorName(operatorName);
            refundOrder.setOperatorPhone(operatorPhone);
            refundOrder.setRemark(remark);
            refundOrderDao.update(refundOrder);
        }
        return resMap;
    }

    @Override
    public Double refundMoney(Double money, Long fineMoney, Integer userId, String buyOrderNO,
                              AdaPayConfig adaPayConfig, Integer adAccountId, Integer operatorId, String operatorName, String operatorPhone,
                              Integer sendMsg, String remark) {
        Double allMoney = money + (fineMoney == null ? 0 : fineMoney);
        Double refundMoney = 0d;
        User user = userService.getByUserId(userId);
        if (user == null) {
            log.warn("用户不存在");
            return 0d;
        }
        /**退单*/
        if (buyOrderNO != null) {
            userService.lockUserRefund(userId);
            if (!redisService.setNx(RedisConstant.REFUND_LOCK + userId, RedisConstant.REFUND_LOCK, 5 * 60) || refundOrderDao.countPendingOrder(userId) > 0) {
                throw new BaseException("-3070", "正在退款中,请稍后再试");
            }
            try {
                RideLog rideLog = rideLogService.getByOrderNO(buyOrderNO);
                String transactionLogRemark = null;
                log.info("订单{}进行退款，罚款fineMoney为{}，其他消费金额money为{}",buyOrderNO,fineMoney,money);
                /**罚款退款*/
                if (fineMoney != null && fineMoney > 0) {
                    if (rideLog != null) {
                        transactionLogRemark = "罚款费用%.2f元";
                    }
                    Double fineRefundMoney = refundHandler(fineMoney.doubleValue(), userId, buyOrderNO, adaPayConfig, adAccountId, operatorId, operatorName, operatorPhone, remark, true, rideLog, transactionLogRemark);
                    refundMoney += fineRefundMoney;
                }
                /**骑行退款，卡券退款*/
                if (money != null && money > 0) {
                    if (rideLog != null) {
                        transactionLogRemark = "骑行费用%.2f元";
                    }
                    Double normalRefundMoney = refundHandler(money, userId, buyOrderNO, adaPayConfig, adAccountId, operatorId, operatorName, operatorPhone, remark, false, rideLog, transactionLogRemark);
                    refundMoney += normalRefundMoney;
                }
                /**插入操作日志*/
                if (refundMoney > 0) {
                    Integer rechargeType = null;
                    /**如果是骑行订单*/
                    if (rideLog != null) {
                        RideRefundLog rideRefundLog = new RideRefundLog(adAccountId, rideLog.getOrderNO(), refundMoney.intValue(), new Date(), user.getUserId(), user.getPhone(), operatorId, operatorPhone, rideLog.getOrderNO(), 1);
                        rideRefundLogDao.insertLog(rideRefundLog);
                    } else {
                        Recharge rechargeDB = rechargeService.getByOrderNO(buyOrderNO);
                        /**如果是卡券退款*/
                        if (rechargeDB != null) {
                            rechargeType = rechargeDB.getRechargeType();
                            RefundOpeLog refundOpeLog = new RefundOpeLog(adAccountId, refundMoney.intValue(), new Date(), userId, user.getPhone(), operatorId, operatorPhone, buyOrderNO, rechargeType);
                            refundOpeLogDao.insert(refundOpeLog);
                            log.info("插入退款操作记录refundOpeLog：" + refundOpeLog);
                        }
                    }

                }
                if (sendMsg != null && sendMsg == 1 && refundMoney > 0) {
                    Account brand = accountDao.getByAdAccountId(adAccountId);
                    SmsAuthConfig smsAuthConfig = smsAuthConfigDao.selectSmsConfig(brand.getParentId());
                    String message = "你有一笔订单退款,订单金额为[" + allMoney / 100.0 + "],请前往小程序查看!";
                    if (smsAuthConfig != null) {
                        /**寻程发送短信*/
                        ApiStoreMsgUtils.refundSend(user.getPhone(), message, smsAuthConfig.getSmsCodeKey(), Integer.valueOf(smsAuthConfig.getModelId()));
                    } else {
                        Map<String, Integer> mapSMS = new HashMap<>();
                        mapSMS.put("accountId", user.getAccountId());
                        mapSMS.put("configType", 4);
                        Account brandArea = accountDao.getByAccountId(user.getAccountId());
                        BrandRemoteConfig brandRemoteConfig = smsAuthConfigDao.getByConfigType(mapSMS);
                        if (brandRemoteConfig != null) {
                            String[] strings = brandRemoteConfig.getParamKV().split("&");
                            String accounts = strings[0].substring(strings[0].indexOf("=") + 1);
                            String password = strings[1].substring(strings[1].indexOf("=") + 1);
                            ClzySmsAuthUtil.sendSms(accounts, password, "【" + brandArea.getName() + "】" + message, user.getPhone());
                        }
                    }
                    usermsgDao.add(new UserMsg(null, 0, user.getUserId(), DateUtil.now(), null, 0, "骑行订单退款", message, "", ""));
                }
                return refundMoney;
            } finally {
                redisService.del(RedisConstant.REFUND_LOCK + userId);
            }
        } else {
            /**退用户余额*/
            return userService.returnMoney(adAccountId, allMoney, userId, true, operatorId, operatorName, operatorPhone);
        }

    }

    @Override
    public RefundMoneyReturnDTO refundMoneyNew(Double money, Long fineMoney, Integer userId, String buyOrderNO,
                                               AdaPayConfig adaPayConfig, Integer adAccountId, Integer operatorId, String operatorName, String operatorPhone,
                                               Integer sendMsg, String remark) {
        RefundMoneyReturnDTO refundMoneyReturnDTO = new RefundMoneyReturnDTO();
        Map<String, Object> resMap = new HashMap<>();
        Double allMoney = money + (fineMoney == null ? 0 : fineMoney);
        Double refundMoney = 0d;
        User user = userService.getByUserId(userId);
        if (user == null) {
            log.warn("用户不存在");
            return refundMoneyReturnDTO;
        }
        // 当前退款批次号，仅用于查询同一次请求的分账信息
        String refundBatch = System.currentTimeMillis() + String.format("%06d", ThreadLocalRandom.current().nextInt(0, 1000000));
        /**退单 (骑行订单 或 骑行卡，会员卡，免押卡，优惠券套餐)*/
        if (buyOrderNO != null) {
            // 防止重复点击
            userService.lockUserRefund(userId);
            if (!redisService.setNx(RedisConstant.REFUND_LOCK + userId, RedisConstant.REFUND_LOCK, 5 * 60) || refundOrderDao.countPendingOrder(userId) > 0) {
                throw new BaseException("-3070", "正在退款中,请稍后再试");
            }
            try {
                RideLog rideLog = rideLogService.getByOrderNO(buyOrderNO);
                String transactionLogRemark = null;
                /**罚款退款*/
                if (fineMoney != null && fineMoney > 0) {
                    log.info("进入罚款退款，订单号={}", buyOrderNO);
                    if (rideLog != null) {
                        transactionLogRemark = "罚款费用%.2f元";
                    }
                    resMap = refundHandlerNew(fineMoney.doubleValue(), userId, buyOrderNO, adaPayConfig, adAccountId, operatorId, operatorName, operatorPhone, remark, true, rideLog, transactionLogRemark, sendMsg, true, refundBatch);
                    refundMoney = refundMoney + (Double) resMap.getOrDefault(RefundConstant.REFUNDMONEY, 0d);
                }
                /**骑行/卡券退款*/
                if (money != null && money > 0) {
                    log.info("进入骑行/卡券退款,订单号={}", buyOrderNO);
                    if (rideLog != null) {
                        transactionLogRemark = "骑行费用%.2f元";
                    }
                    resMap = refundHandlerNew(money, userId, buyOrderNO, adaPayConfig, adAccountId, operatorId, operatorName, operatorPhone, remark, false, rideLog, transactionLogRemark, sendMsg, true, refundBatch);
                    refundMoney = refundMoney + (Double) resMap.getOrDefault(RefundConstant.REFUNDMONEY, 0d);
                }
                // 获取当前buyorderNO最后一次执行的退款动作
                String refundNO = (String) resMap.getOrDefault(RefundConstant.REFUNDNO, "0000");
                if (refundMoney > 0) {
                    RefundOrder refundOrder = refundOrderDao.getByRefundNO(refundNO);
                    if (Objects.isNull(refundOrder)) {
                        log.error("退款发生异常，无效的refundNO{}", refundNO);
                        refundMoneyReturnDTO.setRefundMoney(refundMoney);
                        refundMoneyReturnDTO.setRefundBusinessNO(buyOrderNO);
                        return refundMoneyReturnDTO;
                    }

                    String logTag = Objects.isNull(refundOrder.getLogTag()) ? (RefundConstant.APILOG1 + ",") : (refundOrder.getLogTag() + RefundConstant.APILOG1 + ",");
                    refundOrder.setAdAccountId(adAccountId);
                    refundOrder.setLogTag(logTag);
                    // 退款订单总金额（如骑行订单等）
                    refundOrder.setAllMoney(allMoney);
                    // 已退 骑行订单（骑行消费+罚款金额）或卡券 的 总金额
                    refundOrder.setAlreadyRefundMoney(refundMoney);
                    refundOrderDao.update(refundOrder);
                    log.info("退款订单总金额{},已退 骑行订单总金额{},refundOrder={}", allMoney, refundMoney, refundOrder);
                }
                refundMoneyReturnDTO.setRefundMoney(refundMoney);
                refundMoneyReturnDTO.setRefundBusinessNO(buyOrderNO);
                return refundMoneyReturnDTO;
            } finally {
//                redisService.del(RedisConstant.REFUND_LOCK + userId);
            }
        } else {
            /**退用户余额*/
            return userService.returnMoneyNew(adAccountId, allMoney, userId, true, operatorId, operatorName, operatorPhone, refundBatch);
        }

    }

    private Integer getTransactionTypeByRechargeType(Integer rechargeType) {
        if (rechargeType.equals(RechargeConstant.recharge_Mem)) {
            return TransationLogConstant.BUSINESS_REFUND_MEM;
        }
        if (rechargeType.equals(RechargeConstant.recharge_rideCard)) {
            return TransationLogConstant.BUSINESS_REFUND_RIDECARD;
        }
        if (rechargeType.equals(RechargeConstant.recharge_vip)) {
            return TransationLogConstant.BUSINESS_REFUND_VIP;
        }
        if (rechargeType.equals(RechargeConstant.recharge_meal)) {
            return TransationLogConstant.BUSINESS_REFUND_MEAL;
        }
        if (rechargeType.equals(RechargeConstant.recharge_deposit)) {
            return TransationLogConstant.BUSINESS_USER_REFUND_DEPOSIT;
        }
        if (rechargeType.equals(RechargeConstant.recharge_zff)) {
            return TransationLogConstant.BUSINESS_BIKE_REFUND;
        }
        if (rechargeType.equals(RechargeConstant.recharge_pay)) {
            return TransationLogConstant.BUSINESS_USER_REFUNDED_BALANCE;
        }
        if (rechargeType.equals(RechargeConstant.recharge_returnBike)) {
            return TransationLogConstant.BUSINESS_BIKE_REFUND;
        }
        return null;
    }

    private Integer getRefundLogChangeTypeByRechargeType(Integer rechargeType) {
        if (rechargeType.equals(RechargeConstant.recharge_Mem)) {
            return RefundLogContent.depositCard_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_rideCard)) {
            return RefundLogContent.rideCard_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_vip)) {
            return RefundLogContent.vipCard_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_meal)) {
            return RefundLogContent.couponCard_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_deposit)) {
            return RefundLogContent.deposit_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_zff)) {
            return RefundLogContent.rideLog_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_pay)) {
            return RefundLogContent.balance_Refund;
        }
        if (rechargeType.equals(RechargeConstant.recharge_returnBike)) {
            return RefundLogContent.rideLog_Refund;
        }
        return null;
    }

    private Integer getUserCapitalChangeCapitalTypeByRechargeType(Integer rechargeType) {
        if (rechargeType.equals(RechargeConstant.recharge_Mem)) {
            return PayPlatformContent.PAY_CARD;
        }
        if (rechargeType.equals(RechargeConstant.recharge_rideCard)) {
            return PayPlatformContent.PAY_CARD;
        }
        if (rechargeType.equals(RechargeConstant.recharge_vip)) {
            return PayPlatformContent.PAY_CARD;
        }
        if (rechargeType.equals(RechargeConstant.recharge_meal)) {
            return PayPlatformContent.PAY_CARD;
        }
        if (rechargeType.equals(RechargeConstant.recharge_deposit)) {
            return PayPlatformContent.PAY_DEPOSIT;
        }
        if (rechargeType.equals(RechargeConstant.recharge_zff)) {
            return PayPlatformContent.PAY_RIDELOG_PAY;
        }
        if (rechargeType.equals(RechargeConstant.recharge_pay)) {
            return PayPlatformContent.PAY_BALANCE;
        }
        if (rechargeType.equals(RechargeConstant.recharge_returnBike)) {
            return PayPlatformContent.PAY_RIDELOG_PAY;
        }
        return null;
    }

    private Integer getUserCapitalChangeBusinessTypeByRechargeType(Integer rechargeType) {
        if (rechargeType.equals(RechargeConstant.recharge_Mem)) {
            return BusinessConstant.BUSINESS_REFUND_MEM;
        }
        if (rechargeType.equals(RechargeConstant.recharge_rideCard)) {
            return BusinessConstant.BUSINESS_REFUND_RIDECARD;
        }
        if (rechargeType.equals(RechargeConstant.recharge_vip)) {
            return BusinessConstant.BUSINESS_REFUND_VIP;
        }
        if (rechargeType.equals(RechargeConstant.recharge_meal)) {
            return BusinessConstant.BUSINESS_REFUND_MEAL;
        }
        if (rechargeType.equals(RechargeConstant.recharge_deposit)) {
            return BusinessConstant.BUSINESS_USER_REFUND_DEPOSIT;
        }
        if (rechargeType.equals(RechargeConstant.recharge_zff)) {
            return BusinessConstant.BUSINESS_BIKE_REFUND;
        }
        if (rechargeType.equals(RechargeConstant.recharge_pay)) {
            return BusinessConstant.BUSINESS_USER_REFUNDED_BALANCE;
        }
        if (rechargeType.equals(RechargeConstant.recharge_returnBike)) {
            return BusinessConstant.BUSINESS_BIKE_REFUND;
        }
        return null;
    }

    private String getUserCapitalChangeRemark(Integer businessType) {
        if (BusinessConstant.BUSINESS_USER_REFUNDED_BALANCE.equals(businessType)) {
            return "用户退余额";
        }
        if (BusinessConstant.BUSINESS_BIKE_REFUND.equals(businessType)) {
            return "骑行退款";
        }
        if (BusinessConstant.BUSINESS_USER_REFUND_DEPOSIT.equals(businessType)) {
            return "用户退押金";
        }
        if (BusinessConstant.BUSINESS_REFUND_RIDECARD.equals(businessType)) {
            return "骑行卡退款";
        }
        if (BusinessConstant.BUSINESS_REFUND_MEM.equals(businessType)) {
            return "免押卡退款";
        }
        if (BusinessConstant.BUSINESS_REFUND_VIP.equals(businessType)) {
            return "会员卡退款";
        }
        if (BusinessConstant.BUSINESS_REFUND_MEAL.equals(businessType)) {
            return "优惠券套餐退款";
        }
        return "";
    }

    @Override
    public void pushRefundDetailLog(User user, Account account, Double refundMoney, String refundNO, String refundBusinessNO,
                                    Recharge recharge, Integer operatorId, String operatorName, String operatorPhone,
                                    Integer businessType, String rideOrderNo, String transactionLogRemark, Date time) {
        /**获取原区域id*/
        UserToAgent userToAgent = userToAgentDao.getByUserId(user.getUserId());
        Integer originalAccountId = null;
        if (userToAgent != null) {
            originalAccountId = userToAgent.getFirstId();
        }
        /**兼容区域为空*/
        Integer accountId = null;
        String accountName = null;
        if (account != null) {
            accountId = account.getAccountId();
            accountName = account.getName();
        }

        Date now = new Date();
        if (Objects.nonNull(time)) {
            now = time;
        }
        String merchantNo = null;
        Integer payPlatform = null;
        payPlatform = userService.getPayPlatformTypeByRecharge(recharge);
        merchantNo = recharge.getOrderNO();
        Integer capitalType = getUserCapitalChangeCapitalTypeByRechargeType(recharge.getRechargeType());
        if (businessType == null) {
            businessType = getUserCapitalChangeBusinessTypeByRechargeType(recharge.getRechargeType());
        }
        RideLog rideLog = rideLogService.getByOrderNO(rideOrderNo);
        if (rideLog != null) {
            businessType = BusinessConstant.BUSINESS_BIKE_REFUND;
            capitalType = PayPlatformContent.PAY_RIDELOG_PAY;
        }
        /**退单，退卡，开始金额都是退款的金额*/
        Long changeStartMoney = 0L;
        Long changeEndMoney = 0L;
        /**如果是余额退款*/
        if (businessType != null && businessType.equals(BusinessConstant.BUSINESS_USER_REFUNDED_BALANCE)) {
            User userDb = userService.getByUserId(user.getUserId());
            changeStartMoney = userDb.getMoney().longValue();
            changeEndMoney = changeStartMoney - refundMoney.longValue();
        }
        Integer transactionType = null;
        if (businessType != null && businessType.equals(BusinessConstant.BUSINESS_USER_REFUND_DEPOSIT)) {
            capitalType = PayPlatformContent.PAY_DEPOSIT;
            User userDb = userService.getByUserId(user.getUserId());
            changeStartMoney = userDb.getDepositMoney().longValue();
//            changeEndMoney = changeStartMoney - refundMoney.longValue();
            changeEndMoney = 0L;
            transactionType = TransationLogConstant.BUSINESS_USER_REFUND_DEPOSIT;
        }

        UserCapitalChange userCapitalChange = new UserCapitalChange(user.getUserId(), user.getPhone(), user.getName(), accountId,
                user.getAccountId(), changeStartMoney, refundMoney.longValue(), changeEndMoney,
                IncomeTypeContent.inComeRefund, capitalType, businessType, rideOrderNo, operatorId, operatorPhone, operatorName,
                refundBusinessNO, refundNO, now.getTime(), getUserCapitalChangeRemark(businessType), originalAccountId);
        pushMsgLogService.sendPushLog(JSON.toJSONString(userCapitalChange), TableNameConstant.USERCAPITALCHANGE);

        if (transactionType == null) {
            transactionType = getTransactionTypeByRechargeType(recharge.getRechargeType());
        }
        if (rideLog != null) {
            transactionType = TransationLogConstant.BUSINESS_BIKE_REFUND;
        }
        if (transactionLogRemark != null) {
            transactionLogRemark = String.format(transactionLogRemark, new BigDecimal(refundMoney.toString()).divide(new BigDecimal(100)));
            transactionLogRemark = DateUtil.format(now, "yyyy-MM-dd HH:mm:ss") + transactionLogRemark;
        }

        TransationLog transationLog = new TransationLog(null, refundNO, user.getUserId(),
                user.getPhone(), user.getName(), accountId, user.getAccountId(), accountName,
                refundMoney.longValue(), IncomeTypeContent.inComeRefund, now, now, now,
                payPlatform, transactionType, refundMoney.longValue(),
                now, operatorId, operatorPhone, transactionLogRemark, merchantNo, refundBusinessNO, TransationLogConstant.TRANSACTION_STATE_SUCCESS, operatorName);
        pushMsgLogService.sendPushLog(JSON.toJSONString(transationLog), TableNameConstant.TRANSACTIONLOG);
        /**更新充值记录已退款金额*/
        if (recharge != null) {
            transationLogDao.updateRefundMoneyByOrderNO(recharge.getOrderNO(), refundMoney.longValue());
        }
    }

    @Override
    public void pushRefundLog(User user, Account account, Double refundMoney, String businessNO,
                              List<String> merchantNOList, Recharge recharge, Integer changeType, String rideOrderNo, Integer operatorId, String operatorName, String operatorPhone, String remark, Date time) {
        Date now = new Date();
        if (time != null) {
            now = time;
        }
        /**兼容区域为空*/
        Integer accountId = null;
        String accountName = null;
        if (account != null) {
            accountId = account.getAccountId();
            accountName = account.getName();
        }
        if (changeType == null) {
            changeType = getRefundLogChangeTypeByRechargeType(recharge.getRechargeType());
        }
        /**兼容欠款补交退款单独记录*/
    /*if(recharge!=null&&recharge.getRechargeType()==RechargeConstant.recharge_pay&&"欠款补交".equals(recharge.getRemark())){
      changeType=RefundLogContent.laterMoney_Refund;
    }*/
        String merchantNO = String.join(",", merchantNOList);
        RefundLog refundLog = new RefundLog(null, user.getUserId(), user.getPhone(), user.getName(), accountId,
                accountName, user.getAccountId(), now, operatorId, operatorPhone, operatorName,
                refundMoney.longValue(), changeType, remark,
                DateTimeUtil.DateTimeToString(now), businessNO, merchantNO, rideOrderNo);

        pushMsgLogService.sendPushLog(JSON.toJSONString(refundLog), TableNameConstant.REFUNDLOG);
        RideLog rideLog = rideLogService.getByOrderNO(rideOrderNo);
        if (rideLog != null) {
            RideLogDetails rideLogDetails = rideLogDetailsDao.getByOrderId(rideOrderNo);

            if (rideLogDetails != null) {
                Long deductionCyclingMoney = rideLogDetails.getDeductionCyclingMoney();
                List<RefundLog> refundLogs = refundLogDao.selectByOrderId(rideLogDetails.getOrderId());
                Long hasRefundCyclingMoney = 0l;
                for (RefundLog item : refundLogs) {
                    if (item.getChangeType().equals(RefundLogContent.rideLog_Refund)) {
                        hasRefundCyclingMoney += item.getChangeMoney();
                    }
                }
                /**骑行费用退完才记录抵扣费用日志*/
                if (hasRefundCyclingMoney + refundMoney >= deductionCyclingMoney) {
                    Long peopleModiftDeductionMoney = rideLogDetails.getPeopleModiftDeductionMoney();
                    Long otherDeductionMoney = rideLogDetails.getOtherDeductionMoney();
                    Integer deductionChangeType = null;
                    String deductionRemark = "";

                    if (peopleModiftDeductionMoney != null && peopleModiftDeductionMoney > 0) {
                        deductionChangeType = RefundLogContent.peopleModiftDeductionMoney_Refund;
                        deductionRemark = "人工修改订单抵扣费用";
                        RefundLog deductionRefundLog = new RefundLog(null, user.getUserId(), user.getPhone(), user.getName(), accountId,
                                accountName, user.getAccountId(), now, operatorId, operatorPhone, operatorName,
                                peopleModiftDeductionMoney, deductionChangeType, deductionRemark,
                                DateTimeUtil.DateTimeToString(now), businessNO, merchantNO, rideOrderNo);
                        pushMsgLogService.sendPushLog(JSON.toJSONString(deductionRefundLog), TableNameConstant.REFUNDLOG);
                    }
                    if (otherDeductionMoney != null && otherDeductionMoney > 0) {
                        deductionChangeType = RefundLogContent.otherDeductionMoney_Refund;
                        deductionRemark = "其他抵扣费用";
                        RefundLog deductionRefundLog = new RefundLog(null, user.getUserId(), user.getPhone(), user.getName(), accountId,
                                accountName, user.getAccountId(), now, operatorId, operatorPhone, operatorName,
                                otherDeductionMoney, deductionChangeType, deductionRemark,
                                DateTimeUtil.DateTimeToString(now), businessNO, merchantNO, rideOrderNo);
                        pushMsgLogService.sendPushLog(JSON.toJSONString(deductionRefundLog), TableNameConstant.REFUNDLOG);
                    }
                }


            }
        }
    }

    /**
     * 余额退款
     *
     * @param recharge     充值订单
     * @param adaPayConfig 支付配置
     * @param isCashAll    是否全额分账
     * @param user         用户信息
     * @param money        退款金额
     * @return
     */
    @Override
    public double refund(Account account, Recharge recharge, AdaPayConfig adaPayConfig, boolean isCashAll, User user, Double money,
                         String refundNO, String refundBusinessNO, Integer operatorId, String operatorName, String operatorPhone,
                         String rideOrderNo, String transactionLogRemark) {
        Double refundMoney = 0D;
        AdaPayLog adaPayLog = adaPayLogService.getByOrderNO(recharge.getOrderNO());
        if (adaPayLog == null) {
            return refundMoney;
        }
        /**剩余可退款金额*/
        Double canRefundMoney = adaPayLog.getMoney() - adaPayLog.getCashMoney() - adaPayLog.getRefundMoney();
        if (isCashAll) {
            canRefundMoney = adaPayLog.getMoney() - adaPayLog.getRefundMoney();
        }
        log.info(String.format("单号%s,退款单号%s,订单%s退款,传入金额%s,实际可退款金额%s",refundBusinessNO,refundNO, recharge.getOrderNO(), money, canRefundMoney));
        /**退款金额比可退款金额少，部分退款*/
        if (money < canRefundMoney) {
            canRefundMoney = money;
        }
        log.info("单号{}，订单是否开启充值金额直接分账{}",refundBusinessNO,isCashAll);
        if (isCashAll) {
            List<UserAdaPayLog> userAdaPayLogs = userAdaPayLogService.getByPaymentId(adaPayLog.getAdaPayId());
            if (!userAdaPayLogs.isEmpty()) {
                refundMoney = handelRefund(account, userAdaPayLogs, canRefundMoney, adaPayConfig, user, true, recharge.getOrderNO()
                        , refundBusinessNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, refundNO);
            }
        } else {
            boolean isSucess = PaymentUtil
                    .createReverse(adaPayConfig, adaPayLog.getAdaPayId(), canRefundMoney, refundNO);
            if (isSucess) {
                refundMoney = canRefundMoney;
                userAdaPayMoneyService.add(user, 0, -refundMoney.intValue());
                weixinPayService.sendPayMsg(refundNO, RechargeConstant.PAY_REFUND,null);
                pushRefundDetailLog(user, account, refundMoney, refundNO, refundBusinessNO, recharge, operatorId, operatorName, operatorPhone, null, rideOrderNo, transactionLogRemark, null);
            }
        }
        return refundMoney;
    }

    /**
     * 余额退款（新）
     *
     * @param recharge     充值订单
     * @param adaPayConfig 支付配置
     * @param isCashAll    是否全额分账
     * @param user         用户信息
     * @param money        退款金额
     * @return
     */
    @Override
    public double refundNew(Account account, Recharge recharge, AdaPayConfig adaPayConfig, boolean isCashAll, User user, Double money,
                            String refundNO, String refundBusinessNO, Integer operatorId, String operatorName, String operatorPhone,
                            String rideOrderNo, String transactionLogRemark, Integer sendMsg, boolean isApi, String refundBatch) {
        Double refundMoney = 0D;
        AdaPayLog adaPayLog = adaPayLogService.getByOrderNO(recharge.getOrderNO());
        if (adaPayLog == null) {
            return refundMoney;
        }
        /**剩余可退款金额*/
        Double canRefundMoney = adaPayLog.getMoney() - adaPayLog.getCashMoney() - adaPayLog.getRefundMoney();
        // 延时分账，退款类型为余额，剩余可退余额计算
        if(!isCashAll && Objects.equals(recharge.getRechargeType(),0) && !recharge.getDeposit()){
            canRefundMoney = adaPayLog.getMoney() - adaPayLog.getCashMoney();
        }
        if (isCashAll) {
            canRefundMoney = adaPayLog.getMoney() - adaPayLog.getRefundMoney();
        }
        log.info(String.format("订单%s退款,传入金额%s,实际可退款金额%s", recharge.getOrderNO(), money, canRefundMoney));
        /**退款金额比可退款金额少，部分退款*/
        if (money < canRefundMoney) {
            canRefundMoney = money;
        }
        if (isCashAll) {
            List<UserAdaPayLog> userAdaPayLogs = userAdaPayLogService.getByPaymentId(adaPayLog.getAdaPayId());
            if (!userAdaPayLogs.isEmpty()) {
                log.info("全额分账/实时分账");
                Map<String, Object> resMap = handelRefundNew(account, userAdaPayLogs, canRefundMoney, adaPayConfig, user, true, recharge.getOrderNO()
                        , refundBusinessNO, operatorId, operatorName, operatorPhone, rideOrderNo, transactionLogRemark, refundNO, sendMsg, isApi, refundBatch);
                refundMoney = (Double) resMap.getOrDefault(RefundConstant.REFUNDMONEY, 0d);
            }
        } else {
            log.info("非全额分账/延时分账");
            boolean isSucess = PaymentUtil
                    .createReverse(adaPayConfig, adaPayLog.getAdaPayId(), canRefundMoney, refundNO);
            if (isSucess) {
                refundMoney = canRefundMoney;
                RefundOrder refundOrder = new RefundOrder(refundBusinessNO, refundNO, refundMoney, refundMoney, DateTimeUtil.getNowTime(),
                        RefundConstant.REFUND_PENDING, false, recharge.getOrderNO(), null, null, null, false, null, transactionLogRemark, sendMsg,
                        isApi, null, operatorId, operatorName, operatorPhone, rideOrderNo, RefundConstant.LOG8 + ",", null, null, null,
                        account.getAccountId(), 0d, 0d, null, user.getUserId(), transactionLogRemark, null, null,0d,0d,
                        null, null, null, null);
                refundOrderDao.insert(refundOrder);
            } else {
                RefundOrder refundOrder = new RefundOrder(refundBusinessNO, refundNO, refundMoney, refundMoney, DateTimeUtil.getNowTime(),
                        RefundConstant.REFUND_FAIL, false, recharge.getOrderNO(), null, null, null, false, null, transactionLogRemark, sendMsg,
                        isApi, null, operatorId, operatorName, operatorPhone, rideOrderNo, null, null, null, null,
                        account.getAccountId(), 0d, 0d, null, user.getUserId(), transactionLogRemark, null, null,0d,0d,
                        null, null, null, null);
                refundOrderDao.insert(refundOrder);
            }
        }
        return refundMoney;
    }

    /**
     * 更改退款记录
     *
     * @param adaPayLog 充值记录
     * @param feeMoney  退款金额
     * @param orderNO   退款订单号
     */
    public void editRefund(AdaPayLog adaPayLog, Double feeMoney, String orderNO, User user, boolean isReduce, String remark) {
        if (adaPayLog.getRefundMoney() + feeMoney == adaPayLog.getMoney()) {
            adaPayLog.setState(AdaPayConstant.ADAPAY_LOG_REFUND);
        }
        adaPayLog.setRefundMoney(adaPayLog.getRefundMoney() + feeMoney);
        adaPayLog.setRefundNO(orderNO);
        adaPayLogService.editRefund(adaPayLog);
        if (!isReduce) {
            Recharge recharge = rechargeService.getByOrderNO(adaPayLog.getOrderNO());
            if (recharge != null) {
                addRefundLog(recharge, adaPayLog.getAccountId(), orderNO, feeMoney, user.getUserId(), remark);
            }
        }
        /**添加用户资金变动*/
        if (isReduce) {
            userAdaPayMoneyService.add(user, 0, -feeMoney.intValue());
        }
    }

    /**
     * 添加日志
     *
     * @param recharge    订单
     * @param adAccountId 区域id
     * @param refundNO    退款订单号
     * @param refundMoney 退款金额
     * @param userId      用户id
     */
    @Override
    public void addRefundLog(Recharge recharge, Integer adAccountId, String refundNO, Double refundMoney, Integer userId, String remark) {
        log.info("添加用户退款日志userrefundlog");
        if (recharge.getAdAccountId() > 0) {
            adAccountId = recharge.getAdAccountId();
        }
        UserRefundLog userRefundLog = new UserRefundLog();
        userRefundLog.setAccountId(adAccountId);
        userRefundLog.setOrderMoney(recharge.getMoney());
        userRefundLog.setReturnOrderNO(refundNO);
        userRefundLog.setOrderNO(recharge.getOrderNO());
        userRefundLog.setReturnMoney(refundMoney);
        userRefundLog.setReturnTime(DateTimeUtil.getNowTime());
        userRefundLog.setUserId(userId);
        if (recharge.getType().equals(RechargeConstant.RECHARGE_WEIXIN_APP) || recharge.getType()
                .equals(RechargeConstant.RECHARGE_WEIXIN_XCX)
                || recharge.getType().equals(RechargeConstant.RECHARGE_WEIXIN_AFF) || recharge.getType().equals(
                RechargeConstant.RECHARGE_WEIXIN_ZK_XCX)) {
            userRefundLog.setPlatformType(RechargeConstant.PLATFORM_TYPE_WEIXIN);
        } else if (recharge.getType()
                .equals(RechargeConstant.RECHARGE_PAY_ADAPAY)
                || recharge.getType().equals(RechargeConstant.RECHARGE_PAY_ADAPAY_ZFB)) {
            userRefundLog.setPlatformType(RechargeConstant.PLATFORM_TYPE_ADAPAY);
        } else {
            userRefundLog.setPlatformType(RechargeConstant.PLATFORM_TYPE_ZFB);
        }
        userRefundLog.setServiceType(recharge.getRechargeType());
        userRefundLog.setRemark(remark);
        userRefundLogDao.add(userRefundLog);


    }

    /**
     * 退款处理
     *
     * @param userAdaPayLogs 用户记录
     * @param money          金额
     * @param adaPayConfig   支付配置
     * @param user           用户
     * @return
     */
    public Double handelRefund(Account account, List<UserAdaPayLog> userAdaPayLogs, double money, AdaPayConfig adaPayConfig, User user,
                               boolean isReduce, String remark, String refundBusinessNO, Integer operatorId,
                               String operatorName, String operatorPhone, String rideOrderNo, String transactionLogRemark, String refundNO) {
        Double refundMoney = 0D;
        String feeUserNO = null;
        String mainUserNO = null;
        for (UserAdaPayLog u : userAdaPayLogs) {
            if (u.getType() == 1) {
                feeUserNO = u.getUserNO();
            }
            if (u.getFee() > 0) {
                mainUserNO = u.getUserNO();
            }
        }
        Double refundServiceFee = 0D;
        log.info(String.format("单号%s支付分账对象%s",refundBusinessNO, userAdaPayLogs));
        /**生成*/
        Map<String, List<DivMembers>> map = getRefundDivMember(userAdaPayLogs, money, adaPayConfig.getAccountId());
        log.info(String.format("单号%s计算退款用户信息，退款金额%s,退款对象%s",refundBusinessNO, money, map));
        for (Map.Entry<String, List<DivMembers>> entry : map.entrySet()) {
            String key = entry.getKey();
            List<DivMembers> divMembers = entry.getValue();
            double feeMoney = 0D;
            for (DivMembers members : divMembers) {
                /**用户分账日志记录金额为元，充值记录单位为分，需要兼容*/
                feeMoney = feeMoney + DoubleUtil.parseDouble(Double.parseDouble(members.getAmount()) * 100);
                if (members.getMember_id().equals(feeUserNO)) {
                    refundServiceFee = DoubleUtil.parseDouble(Double.parseDouble(members.getAmount()) * 100);
                }
            }
            String orderNO = OrderNoUtil.getRefundNO();
            if (refundNO != null) {
                orderNO = refundNO;
            }
            log.info("单号{}进行退款，退款单号{}，金额{}",refundBusinessNO,refundNO,feeMoney);
            Map<String, Object> payment = PaymentUtil.executeRefund(adaPayConfig, key, feeMoney, orderNO, JSON.toJSONString(divMembers));
            Boolean refund = false;
            if (payment.get("status").equals(AdaPayConstant.PAY_STATUS_PENDING) || payment.get("status").equals(
                    AdaPayConstant.PAY_STATUS_SUCCEEDED)) {
                refund = true;
            }
            /**退款成功，记录日志*/
            if (refund) {
                String fee_amt = payment.get("fee_amt").toString();
                refundMoney = refundMoney + feeMoney;
                AdaPayLog adaPayLog = adaPayLogService.getByConfirmId(key);
                editRefund(adaPayLog, feeMoney, orderNO, user, isReduce, remark);
                /**修改用户分账退款记录*///实时分账不传递业务订单号
                editUserAdaPayLog(divMembers, adaPayLog.getAdaPayId(), (int) feeMoney,
                        DoubleUtil.parseDouble(Double.parseDouble(fee_amt) * 100).intValue(),
                        (refundServiceFee).intValue(), mainUserNO, isReduce ? null : rideOrderNo,null);
                //添加分账退款日志
                addAdaPayRefundLog(userAdaPayLogs, divMembers, orderNO, (int) feeMoney, (refundServiceFee).intValue(),
                        DoubleUtil.parseDouble(Double.parseDouble(fee_amt) * 100).intValue());
                //下发退款查询消息
                weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_REFUND,null);
                Recharge recharge = rechargeService.getByOrderNO(adaPayLog.getOrderNO());
                pushRefundDetailLog(user, account, feeMoney, orderNO, refundBusinessNO, recharge, operatorId, operatorName, operatorPhone, null, rideOrderNo, transactionLogRemark, null);
            } else {
                log.warn(String.format("refund fail,orderNO:%s,userId:%s", key, user.getUserId()));
            }
        }
        return refundMoney;
    }

    /**
     * 退款处理
     *
     * @param userAdaPayLogs 用户记录
     * @param money          金额
     * @param adaPayConfig   支付配置
     * @param user           用户
     * @return
     */
    public Map<String, Object> handelRefundNew(Account account, List<UserAdaPayLog> userAdaPayLogs, double money, AdaPayConfig adaPayConfig, User user,
                                               boolean isReduce, String remark, String refundBusinessNO, Integer operatorId,
                                               String operatorName, String operatorPhone, String rideOrderNo, String transactionLogRemark, String refundNO, Integer sendMsg, boolean isApi, String refundBatch) {
        Map<String, Object> resMap = new HashMap<>();
        Double refundMoney = 0D;
        String feeUserNO = null;
        String mainUserNO = null;
        for (UserAdaPayLog u : userAdaPayLogs) {
            if (u.getType() == 1) {
                feeUserNO = u.getUserNO();
            }
            if (u.getFee() > 0) {
                mainUserNO = u.getUserNO();
            }
        }
        /**生成退款对象*/
        Map<String, List<DivMembers>> map = new HashMap<>();
        //查询同批次最后一次的汇付退款信息
        RefundOrder refundOrderByRefundBatch = refundOrderDao.getByRefundBatch(refundBatch);
        // 更正后的用户分账信息
        List<UserAdaPayLog> correctedUserAdaPayLogs;
        if(ObjectUtils.isNotEmpty(refundOrderByRefundBatch) && StringUtils.isNotBlank(refundOrderByRefundBatch.getActualUserAdapaylogs())){
            List<UserAdaPayLog> actualUserAdapaylogs = JSON.parseArray(refundOrderByRefundBatch.getActualUserAdapaylogs(), UserAdaPayLog.class);
            // 重新拼接用户分账信息
            correctedUserAdaPayLogs = copyAndUpdateLogs(userAdaPayLogs, actualUserAdapaylogs);
            log.info("更正后的用户分账信息{}", correctedUserAdaPayLogs);
            map = getRefundDivMember(correctedUserAdaPayLogs, money, adaPayConfig.getAccountId());
        } else {
            // 不存在同批次的分账信息走原有的逻辑
            correctedUserAdaPayLogs=userAdaPayLogs;
            map = getRefundDivMember(userAdaPayLogs, money, adaPayConfig.getAccountId());
        }

        log.info(String.format("计算退款用户信息，退款金额%s,退款对象%s", money, map));
        String orderNO = null;
        for (Map.Entry<String, List<DivMembers>> entry : map.entrySet()) {
            String key = entry.getKey();
            List<DivMembers> divMembers = entry.getValue();
            double feeMoney = 0D;
            for (DivMembers members : divMembers) {
                /**用户分账日志记录金额为元，充值记录单位为分，需要兼容*/
                feeMoney = feeMoney + DoubleUtil.parseDouble(Double.parseDouble(members.getAmount()) * 100);
                if (members.getMember_id().equals(feeUserNO)) {
                }
            }
            orderNO = OrderNoUtil.getRefundNO();
            if (refundNO != null) {
                orderNO = refundNO;
            }
            Map<String, Object> payment = PaymentUtil.executeRefund(adaPayConfig, key, feeMoney, orderNO, JSON.toJSONString(divMembers));
            Boolean refund = false;
            String actualUserAdapaylogs=null;
            if (payment.get("status").equals(AdaPayConstant.PAY_STATUS_PENDING) || payment.get("status").equals(
                    AdaPayConstant.PAY_STATUS_SUCCEEDED)) {
                refund = true;
                // 记录退款分账记录的实际退款金额
               actualUserAdapaylogs=JSON.toJSONString(buildActualUserAdaPayLogs(correctedUserAdaPayLogs,  map));
            }
            String rechargeNO = null;
            List<UserAdaPayLog> userAdaPayLogList = userAdaPayLogs.stream().filter(x -> key.equals(x.getConfirmId())).collect(Collectors.toList());
            String paymentId = userAdaPayLogList.get(0).getPaymentId();
            AdaPayLog adaPayLog = adaPayLogService.getByAdaPayId(paymentId);
            rechargeNO = adaPayLog.getOrderNO();
            /**退款成功，记录日志*/
            String refundTime = DateTimeUtil.getNowTime();
            if (refund) {
                String fee_amt = payment.get("fee_amt").toString();
                refundMoney = refundMoney + feeMoney;
                RefundOrder refundOrder = new RefundOrder(refundBusinessNO, orderNO, money, feeMoney, refundTime, RefundConstant.REFUND_PENDING,
                        true, rechargeNO, null, null, null, false, null, remark, sendMsg, isApi, isReduce, operatorId, operatorName,
                        operatorPhone, rideOrderNo, RefundConstant.LOG9 + ",", null, null, null,
                        account.getAccountId(), 0d, 0d, null, user.getUserId(), transactionLogRemark, fee_amt, key,0d,0d,
                        JSON.toJSONString(userAdaPayLogs), actualUserAdapaylogs, refundBatch, null);
                refundOrderDao.insert(refundOrder);
                log.info("插入记录分账退款记录表{}", JSON.toJSONString(refundOrder));
                //下发退款查询消息
                weixinPayService.sendPayMsg(orderNO, RechargeConstant.PAY_REFUND,null);
            } else {
                log.warn(String.format("退款失败,订单号:%s,用户id:%s", key, user.getUserId()));
                RefundOrder refundOrder = new RefundOrder(refundBusinessNO, orderNO, money, feeMoney, refundTime, RefundConstant.REFUND_FAIL,
                        true, rechargeNO, null, null, null, false, null, remark, sendMsg, isApi, isReduce, operatorId, operatorName,
                        operatorPhone, rideOrderNo, null, null, null, null,
                        account.getAccountId(), 0d, 0d, null, user.getUserId(), transactionLogRemark, null, key,0d,0d,JSON.toJSONString(userAdaPayLogs),
                        null, null, payment.getOrDefault("error_msg",null).toString());
                refundOrderDao.insert(refundOrder);
            }
        }
        resMap.put("refundMoney", refundMoney);
        resMap.put("refundNO", orderNO);
        return resMap;
    }

    // 重新拼接用户分账信息
    public static List<UserAdaPayLog> copyAndUpdateLogs(List<UserAdaPayLog> userAdaPayLogs, List<UserAdaPayLog> actualUserAdapaylogs) {
        // 深拷贝原始列表，确保不修改原对象
        List<UserAdaPayLog> copiedLogs = JSON.parseArray(JSON.toJSONString(userAdaPayLogs), UserAdaPayLog.class);

        // 用于匹配查找
        Map<String, UserAdaPayLog> actualMap = actualUserAdapaylogs.stream()
                .collect(Collectors.toMap(
                        log -> log.getPaymentId() + "_" + log.getUserNO(),
                        log -> log,
                        (existing, replacement) -> replacement  // 如有重复则使用后者
                ));

        // 遍历 copiedLogs，更新 refundMoney 和 allRefundMoney
        for (UserAdaPayLog log : copiedLogs) {
            String key = log.getPaymentId() + "_" + log.getUserNO();
            UserAdaPayLog actualLog = actualMap.get(key);

            if (actualLog != null) {
                log.setAllRefundMoney(actualLog.getAllRefundMoney());
                log.setRefundMoney(actualLog.getRefundMoney());
            }
        }

        return copiedLogs;
    }

    // 构造本次还未回调前的用户分账信息
    public static List<UserAdaPayLog> buildActualUserAdaPayLogs(List<UserAdaPayLog> userAdaPayLogs,
                                                         Map<String, List<DivMembers>> divMap) {
        List<UserAdaPayLog> actualUserAdapaylogs = new ArrayList<>();

        // 1. 计算所有 DivMembers.amount 的总和，作为 allRefundMoney（单位：分）
        int allRefundMoney = divMap.values().stream()
                .flatMap(List::stream)
                .map(DivMembers::getAmount)
                .map(amountStr -> new BigDecimal(amountStr).multiply(BigDecimal.valueOf(100)).intValue())
                .reduce(0, Integer::sum);

        // 2. 遍历 userAdaPayLogs，进行深拷贝 + 设置 refundMoney 和 allRefundMoney
        for (UserAdaPayLog originalLog : userAdaPayLogs) {
            UserAdaPayLog copy = new UserAdaPayLog();
            BeanUtils.copyProperties(originalLog, copy);

            copy.setAllRefundMoney(allRefundMoney+ copy.getAllRefundMoney()); // 设置统一的 allRefundMoney

            List<DivMembers> divMembersList = divMap.get(copy.getConfirmId());
            if (divMembersList != null) {
                for (DivMembers member : divMembersList) {
                    if (member.getMember_id().equals(copy.getUserNO())) {
                        BigDecimal amountYuan = new BigDecimal(member.getAmount());
                        int amountFen = amountYuan.multiply(BigDecimal.valueOf(100)).intValue();
                        copy.setRefundMoney(amountFen + copy.getRefundMoney());
                        break;
                    }
                }
            }
            actualUserAdapaylogs.add(copy);
        }
        return actualUserAdapaylogs;
    }

    /**
     * 添加分账记录日志
     *
     * @param userAdaPayLogs   分账订单信息
     * @param divMembers       分账用户信息
     * @param orderNO          退款订单号
     * @param money            退款金额
     * @param refundServiceFee 退款服务费
     * @param fee              退款退还的手续费
     */
    @Override
    public void addAdaPayRefundLog(List<UserAdaPayLog> userAdaPayLogs, List<DivMembers> divMembers, String orderNO, Integer money, Integer refundServiceFee, Integer fee) {
        List<AdapayRefundLog> logs = new ArrayList<>();
        Date time = new Date();
        for (UserAdaPayLog u : userAdaPayLogs) {
            for (DivMembers d : divMembers) {
                if (u.getUserNO().equals(d.getMember_id())) {
                    AdapayRefundLog adapayRefundLog = new AdapayRefundLog();
                    adapayRefundLog.setAccountId(u.getAccountId());
                    adapayRefundLog.setBrandId(u.getBrandId());
                    adapayRefundLog.setMoney(DoubleUtil.parseDouble(Double.parseDouble(d.getAmount()) * 100).intValue());
                    adapayRefundLog.setServiceFee(refundServiceFee);
                    adapayRefundLog.setOrderNO(orderNO);
                    adapayRefundLog.setPaymentId(u.getPaymentId());
                    adapayRefundLog.setProportion(u.getProportion());
                    if (u.getFee() > 0) {
                        adapayRefundLog.setFee(fee);
                    } else {
                        adapayRefundLog.setFee(0);
                    }
                    adapayRefundLog.setUserNO(u.getUserNO());
                    adapayRefundLog.setAddTime(time);
                    logs.add(adapayRefundLog);
                }
            }
        }
        if (logs.size() > 0) {
            adapayRefundLogDao.addBatch(logs);
        }
    }

    /**
     * 修改用户订单记录
     *
     * @param divMembers
     * @param adaPayId
     */
    public void editUserAdaPayLog(List<DivMembers> divMembers, String adaPayId, Integer allRefundMoney
            , Integer refundFee, Integer refundServiceFee, String mainUserNO, String buyOrderNo,DateTime time) {
        for (DivMembers d : divMembers) {
            UserAdaPayLog userAdaPayLog = new UserAdaPayLog();
            userAdaPayLog.setPaymentId(adaPayId);
            userAdaPayLog.setRefundMoney(DoubleUtil.parseDouble(Double.parseDouble(d.getAmount()) * 100).intValue());
            userAdaPayLog.setUserNO(d.getMember_id());
            userAdaPayLog.setAllRefundMoney(allRefundMoney);
            userAdaPayLog.setBuyOrderNO(buyOrderNo);
            if (d.getMember_id().equals(mainUserNO)) {
                userAdaPayLog.setRefundFee(refundFee);
            } else {
                userAdaPayLog.setRefundFee(0);
            }
            userAdaPayLog.setRefundServiceFee(refundServiceFee);
            userAdaPayLog.setRefundTime(time);
            userAdaPayLogService.editRefund(userAdaPayLog);
        }

    }

//    public static void main(String[] args) {
//        List<UserAdaPayLog> userAdaPayLogs  = new ArrayList<>();
//
//        UserAdaPayLog userAdaPayLog1 = new UserAdaPayLog();
//        userAdaPayLog1.setUserNO("uqbikeSubAccount_267_145_1670316325724");
//        userAdaPayLog1.setAccountId(11994);
//        userAdaPayLog1.setBrandId(267);
//        userAdaPayLog1.setOrderNO("T_G_GX_VIP_240524134030_418608");
//        userAdaPayLog1.setFee(0);
//        userAdaPayLog1.setProportion(0.55);
//        userAdaPayLog1.setMoney(27);
//        userAdaPayLog1.setPaymentId("002212024052413403110639954133014605824");
//        userAdaPayLog1.setConfirmId("002212024052413403110639954133014605824");
//        userAdaPayLog1.setBuyOrderNO("T_G_GX_VIP_240524134030_418608");
//        userAdaPayLog1.setBuyOrderType(4);
//        userAdaPayLog1.setRefundMoney(0);
//        userAdaPayLog1.setRechargeMoney(50);
//        userAdaPayLog1.setServiceFee(0);
//        userAdaPayLog1.setType(0);
//        userAdaPayLog1.setAllRefundMoney(0);
//        userAdaPayLog1.setRefundFee(0);
//        userAdaPayLog1.setRefundServiceFee(0);
//
//
//        UserAdaPayLog userAdaPayLog = new UserAdaPayLog();
//        userAdaPayLog.setUserNO("uqbikeSubAccount_267_145_1670316325724");
//        userAdaPayLog.setAccountId(11994);
//        userAdaPayLog.setBrandId(267);
//        userAdaPayLog.setOrderNO("T_G_GX_VIP_240524134030_418608");
//        userAdaPayLog.setFee(0);
//        userAdaPayLog.setProportion(0.45);
//        userAdaPayLog.setMoney(23);
//        userAdaPayLog.setPaymentId("002212024052413403110639954133014605824");
//        userAdaPayLog.setConfirmId("002212024052413403110639954133014605824");
//        userAdaPayLog.setBuyOrderNO("T_G_GX_VIP_240524134030_418608");
//        userAdaPayLog.setBuyOrderType(4);
//        userAdaPayLog.setRefundMoney(0);
//        userAdaPayLog.setRechargeMoney(50);
//        userAdaPayLog.setServiceFee(0);
//        userAdaPayLog.setType(0);
//        userAdaPayLog.setAllRefundMoney(0);
//        userAdaPayLog.setRefundFee(0);
//        userAdaPayLog.setRefundServiceFee(0);
//
//        userAdaPayLogs.add(userAdaPayLog1);
//        userAdaPayLogs.add(userAdaPayLog);
//
//        AdaPayServiceImpl impl = new AdaPayServiceImpl();
//        Map<String, List<DivMembers>> refundDivMember = impl.getRefundDivMember(userAdaPayLogs, 4D, 11994);
//        System.out.println(11111111);
//    }

    /**
     * 获取退款对象
     *
     * @param userAdaPayLogs
     * @return
     */
    public Map<String, List<DivMembers>> getRefundDivMember(List<UserAdaPayLog> userAdaPayLogs, double money, Integer accountId) {
        Map<String, List<DivMembers>> map = new HashMap<>();
        /**服务费账号*/
        String feeNO = null;
        /**部分退款订单号*/
        String isLess = null;
        List<UserDivide> userDivides = new ArrayList<>();

        Double needRefundMoney = money;

        userAdaPayLogs = userAdaPayLogs.stream().sorted(Comparator.comparing(UserAdaPayLog::getType)).collect(
                Collectors.toList());
        /**循环计算分账费用*/
        for (UserAdaPayLog u : userAdaPayLogs) {
            List<DivMembers> list = map.get(u.getConfirmId());

            if (list == null) {
                list = new ArrayList<>();
                /**计算总金额与要退款金额比较*/
                Integer orderMoney = u.getRechargeMoney() - u.getAllRefundMoney();
                if (orderMoney > money) {
                    isLess = u.getConfirmId();
                }
            }
            String isFee = "N";
            if (u.getFee() > 0) {
                isFee = "Y";
            }
            if (isLess != null && u.getConfirmId().equals(isLess)) {
                UserDivide userDivide = new UserDivide();
                userDivide.setProportion(u.getProportion());
                if (u.getFee() > 0) {
                    userDivide.setMainUser(1);
                } else {
                    userDivide.setMainUser(0);
                }
                userDivide.setUserNO(u.getUserNO());
                userDivides.add(userDivide);
                needRefundMoney = needRefundMoney - (money * u.getProportion());
                BigDecimal bd = new BigDecimal(needRefundMoney);
                bd = bd.setScale(0, RoundingMode.HALF_EVEN);
                needRefundMoney = bd.doubleValue();
            } else {
                /**服务费用*/
                Integer cashMoney = u.getMoney() - u.getRefundMoney();
                if (cashMoney > 0) {
                    DivMembers divMembers = new DivMembers(u.getUserNO(), String.format("%.2f", cashMoney.doubleValue() / 100), isFee);
                    list.add(divMembers);
                    needRefundMoney = needRefundMoney - cashMoney;
                    money = money - cashMoney;
                }
            }
            map.put(u.getConfirmId(), list);

            if (u.getType() == 1) {
                feeNO = u.getUserNO();
            }
            if (needRefundMoney <= 0) {
                break;
            }
        }
        /**部分分账订单退款需要重新计算费用*/
        if (isLess != null) {
            UserDivide userDivide = null;
            List<UserDivide> userDivideList = new ArrayList<>();
            /**需要去除服务费账号*/
            for (UserDivide u : userDivides) {
                if (!u.getUserNO().equals(feeNO)) {
                    userDivideList.add(u);
                } else {
                    userDivide = u;
                }
            }
            map.put(isLess, AdapayUtil.getCashUser(userDivideList, money, userDivide));
        }
        return map;
    }

//    public static void main(String[] args) {
//        AdaPayServiceImpl adaPayService = new AdaPayServiceImpl();
//        List<UserAdaPayLog> userAdaPayLogs = new ArrayList<>();
//
//        UserAdaPayLog userAdaPayLog = new UserAdaPayLog();
//        userAdaPayLog.setUserNO("uqbikeSubAccount_267_144_1719978691589");
//        userAdaPayLog.setAccountId(500158);
//        userAdaPayLog.setBankNO(null);
//        userAdaPayLog.setOrderNO("T_G_GX_PAY_240719095708_812486");
//        userAdaPayLog.setProportion(0.55);
//        userAdaPayLog.setMoney(11);
//        userAdaPayLog.setFee(0);
//        userAdaPayLog.setPaymentId("002212024071909570910660191643234111488");
//        userAdaPayLog.setConfirmId("002212024071909570910660191643234111488");
//        userAdaPayLog.setAddTime(new Date());
//        userAdaPayLog.setRemark(null);
//        userAdaPayLog.setBrandId(267);
//        userAdaPayLog.setBuyOrderNO("T_G_GX_PAY_240719095708_812486");
//        userAdaPayLog.setBuyOrderType(0);
//        userAdaPayLog.setRefundMoney(0);
//        userAdaPayLog.setRefundTime(null);
//        userAdaPayLog.setRechargeMoney(20);
//        userAdaPayLog.setServiceFee(0);
//        userAdaPayLog.setType(0);
//        userAdaPayLog.setAllRefundMoney(0);
//        userAdaPayLog.setRefundFee(0);
//        userAdaPayLog.setRefundServiceFee(0);
//
//
//        UserAdaPayLog userAdaPayLog1 = new UserAdaPayLog();
//        userAdaPayLog1.setUserNO("uqbikeSubAccountTest_267_109");
//        userAdaPayLog1.setAccountId(500158);
//        userAdaPayLog1.setBankNO(null);
//        userAdaPayLog1.setOrderNO("T_G_GX_PAY_240719095708_812486");
//        userAdaPayLog1.setProportion(0.45);
//        userAdaPayLog1.setMoney(9);
//        userAdaPayLog1.setFee(0);
//        userAdaPayLog1.setPaymentId("002212024071909570910660191643234111488");
//        userAdaPayLog1.setConfirmId("002212024071909570910660191643234111488");
//        userAdaPayLog1.setAddTime(new Date());
//        userAdaPayLog1.setRemark(null);
//        userAdaPayLog1.setBrandId(267);
//        userAdaPayLog1.setBuyOrderNO("T_G_GX_PAY_240719095708_812486");
//        userAdaPayLog1.setBuyOrderType(0);
//        userAdaPayLog1.setRefundMoney(0);
//        userAdaPayLog1.setRefundTime(null);
//        userAdaPayLog1.setRechargeMoney(20);
//        userAdaPayLog1.setServiceFee(0);
//        userAdaPayLog1.setType(0);
//        userAdaPayLog1.setAllRefundMoney(0);
//        userAdaPayLog1.setRefundFee(0);
//        userAdaPayLog1.setRefundServiceFee(0);
//
//
//
//
//        userAdaPayLogs.add(userAdaPayLog);
//        userAdaPayLogs.add(userAdaPayLog1);
//
//        Map<String, List<DivMembers>> refundDivMember = adaPayService.getRefundDivMember(userAdaPayLogs, 16, 500158);
//
//        System.out.println(refundDivMember);
//    }
    /**
     * 添加费用记录
     *
     * @param orderNO
     * @param adAccountId
     * @param user
     * @param money
     * @param rideMoney
     * @return
     */
    @Override
    public RideFeeLog addRideFeeLog(String orderNO, Integer adAccountId, User user, Integer money, Integer rideMoney, Integer type) {
        RideFeeLog rideFeeLog = rideFeeLogDao.getByOrderNo(orderNO);
        if (rideFeeLog == null) {
            /**记录订单扣费记录*/
            rideFeeLog = new RideFeeLog();
            rideFeeLog.setOrderNO(orderNO);
            rideFeeLog.setAccountId(adAccountId);
            rideFeeLog.setBrandId(user.getAccountId());
            rideFeeLog.setUserId(user.getUserId());
            rideFeeLog.setAddTime(new Date());
            rideFeeLog.setMoney(money);
            rideFeeLog.setRealMoney(rideMoney);
            rideFeeLog.setOverMoney(money - rideMoney);
            rideFeeLog.setState(1);
            rideFeeLog.setType(type);
            rideFeeLogDao.insert(rideFeeLog);
        } else {
            rideFeeLog.setRealMoney(rideFeeLog.getRealMoney() + rideMoney);
            rideFeeLog.setOverMoney(rideFeeLog.getMoney() - rideFeeLog.getRealMoney());
            rideFeeLogDao.update(rideFeeLog);
        }
        return rideFeeLog;
    }

    /**
     * 分账
     *
     * @param adaPayConfig 支付配置信息
     * @param money        分账金额
     * @param adaPayLog    充值记录
     * @param type         订单分账完成后状态
     * @param list         分账用户列表
     * @param userMap      分账用户比例缓存
     */
    public Boolean cash(AdaPayConfig adaPayConfig, Double money,
                        AdaPayLog adaPayLog, Integer type, List<DivMembers> list, Map<String, UserDivide> userMap, String buyOrderNO,
                        UserDivide userDivide, Double orderMoney) {
        String orderNO = "GXBIKECASH" + System.currentTimeMillis() + TenpayUtil.buildRandom(6);
        /**发起延时分账*/
        try {
            Map<String, Object> map = PaymentUtil
                    .createConfirm(adaPayConfig, adaPayLog.getAdaPayId(), orderNO, money / 100, list);
            String status = map.get("status").toString();
            if (status != null && "succeeded".equalsIgnoreCase(status)) {
                /**手续费*/
                String fee_amt = map.get("fee_amt").toString();
                /**支付确认订单号*/
                String confirmId = map.get("id").toString();
                Double serviceFee = getServiceFee(list, userDivide);
                List<UserAdaPayLog> userAdaPayLogs = new ArrayList<>();
                for (DivMembers d : list) {
                    /**记录分账详细*/
                    UserAdaPayLog userAdaPayLog = new UserAdaPayLog();
                    userAdaPayLog.setUserNO(d.getMember_id());
                    userAdaPayLog.setAccountId(adaPayLog.getAccountId());
                    userAdaPayLog.setBrandId(adaPayConfig.getAccountId());
                    userAdaPayLog.setBuyOrderNO(buyOrderNO);
                    userAdaPayLog.setAddTime(new Date());
                    userAdaPayLog.setMoney(DoubleUtil.parseDouble(Double.parseDouble(d.getAmount()) * 100).intValue());
                    userAdaPayLog.setOrderNO(orderNO);
                    userAdaPayLog.setBuyOrderType(adaPayLog.getType());
                    userAdaPayLog.setPaymentId(adaPayLog.getAdaPayId());
                    userAdaPayLog.setRechargeMoney(money.intValue());
                    userAdaPayLog.setType(AdaPayConstant.ADAPAY_TYPE_USER);
                    userAdaPayLog.setServiceFee((serviceFee).intValue());
                    if (userDivide != null && userDivide.getUserNO().equals(d.getMember_id())) {
                        userAdaPayLog.setType(AdaPayConstant.ADAPAY_TYPE_SERVICE);
                    }
                    Integer fee = DoubleUtil.parseDouble(Double.parseDouble(fee_amt) * 100).intValue();
                    /**userMap为空代表是分给账户本身*/
                    if (userMap.isEmpty()) {
                        userAdaPayLog.setFee(fee);
                        userAdaPayLog.setProportion(1.0);
                    } else {
                        if (money.equals(Double.valueOf(d.getAmount()))) {
                            userAdaPayLog.setProportion(1.0);
                            userAdaPayLog.setFee(fee);
                        } else {
                            if (userMap.get(d.getMember_id()) == null) {
                                userAdaPayLog.setProportion(1.0);
                                userAdaPayLog.setFee(fee);
                            } else {
                                if (userMap.get(d.getMember_id()).getMainUser() == 1) {
                                    userAdaPayLog.setFee(fee);
                                } else {
                                    userAdaPayLog.setFee(0);
                                }
                                userAdaPayLog.setProportion(userMap.get(d.getMember_id()).getProportion());
                            }
                        }
                    }
                    userAdaPayLog.setConfirmId(confirmId);
                    userAdaPayLogs.add(userAdaPayLog);
                }
                userAdaPayLogService.addBatch(userAdaPayLogs);

                double caseMoney = adaPayLog.getCashMoney();
                /**修改订单*/
                AdaPayLog adaPayLogDB = new AdaPayLog();
                adaPayLogDB.setCashNO(orderNO);
                adaPayLogDB.setCashMoney(money + caseMoney);
                adaPayLogDB.setUpdateTime(new Date());
                adaPayLogDB.setState(type);
                adaPayLogDB.setOrderNO(adaPayLog.getOrderNO());
                adaPayLogService.edit(adaPayLogDB);
                return true;
            } else {
                log.error("分账失败" + adaPayLog.getAdaPayId() + ",金额=" + money + ",orderNO=" + orderNO);
                return false;
            }
        } catch (Exception e) {
            log.error("分账异常" + adaPayLog.getAdaPayId() + ",金额=" + money + ",orderNO=" + orderNO, e);
            return false;
        }

    }

    /**
     * 获取服务费用
     *
     * @param list
     * @param userDivide
     * @return
     */
    public double getServiceFee(List<DivMembers> list, UserDivide userDivide) {
        Double serviceFee = 0D;
        /**如果扣除了服务费*/
        if (userDivide != null) {
            for (DivMembers divMembers : list) {
                if (userDivide.getUserNO().equals(divMembers.getMember_id())) {
                    serviceFee = DoubleUtil.parseDouble(Double.parseDouble(divMembers.getAmount()) * 100);
                }
            }
        }
        return serviceFee;
    }

    /**
     * 查询是否开启充值金额直接分账
     *
     * @param accountId
     * @return
     */
    @Override
    public boolean getPayType(Integer accountId) {
        /**查询是否开启充值金额直接分账*/
        Boolean cashAll = false;
        BrandRemoteConfig brandRemoteConfig = cacheService.getBrandRemoteConfig(accountId,
                BrandConstant.ADAPAY_MONEY_CASH_TYPE);
        if (brandRemoteConfig != null) {
            Integer button = Integer.valueOf(brandRemoteConfig.getParamKV().substring(brandRemoteConfig.getParamKV().indexOf("=") + 1));
            if (button == 1) {
                cashAll = true;
            }
        }
        return cashAll;
    }

    /**
     * 支付
     *
     * @param adaPayConfig 支付配置
     * @param money        金额
     * @param orderNO      订单号
     * @param openId       用户唯一id
     * @param adAccountId  区域id
     * @param rechargeType 充值类型
     * @param remark       备注
     * @return
     */
    public Map<String, Object> pay(AdaPayConfig adaPayConfig, Double money, String orderNO, String openId, Integer adAccountId, Integer rechargeType, String remark, String buyOrderNO,Integer machineId) {
        Map<String, Object> payment = null;
        /**查询是否开启充值金额直接分账*/
        Boolean cashAll = getPayType(adaPayConfig.getAccountId());
        redisService.add(RedisConstant.ADAPAY_PAY_CASH + orderNO, String.valueOf(cashAll), 5 * 60);
        String depositAccount = getDepositAccount(adaPayConfig.getAccountId());
        //兼容购买商品名称区分品牌和区域
        Account account = cacheService.getAccount(adaPayConfig.getAccountId());
        Account adAccount = cacheService.getAccount(adAccountId);
        remark = account.getName() + "-" + adAccount.getName() + "-" + remark;
        /**充值结束订单实时分账*/

        //4.0.6 添加欠款补交类型
        if ((RechargeConstant.recharge_returnBike == (rechargeType) || RechargeConstant.recharge_vip == (rechargeType) ||
                (RechargeConstant.recharge_QKBJ == (rechargeType) && Objects.equals(delayPayQKBJSwitch.getModel(),DelayPayQKBJSwitch.REAL_TIME))
                || RechargeConstant.recharge_Mem == (rechargeType) || RechargeConstant.recharge_rideCard == (rechargeType)
                || RechargeConstant.recharge_meal == (rechargeType) || (RechargeConstant.recharge_deposit == (rechargeType) && StringUtils.isNotEmpty(depositAccount)) || cashAll)) {

//            List<UserDivide> divides = userDivideService.getByAccountId(adAccountId);
            List<UserDivide> divides = userDivideService.getAreaOrMachineDivide(adAccountId,machineId);
            Map<String, UserDivide> userMap = new HashMap<>();
            for (UserDivide userDivide : divides) {
                userMap.put(userDivide.getUserNO(), userDivide);
            }
            DivMembers divMember = null;
            /**兼容服务费扣取到服务费账户*/
            UserDivide userDivide = getHandelFee(adaPayConfig.getAccountId());
            if (userDivide != null) {
                userMap.put(userDivide.getUserNO(), userDivide);
            }
            List<DivMembers> list = AdapayUtil.getCashUser(divides, money * 100, userDivide);
            if (divMember != null) {
                list.add(divMember);
            }
            /**押金单独处理分账到指定账号*/
            if (StringUtils.isNotEmpty(depositAccount) && RechargeConstant.recharge_deposit == (rechargeType)) {
                list = new ArrayList<>();
                list.add(new DivMembers(depositAccount, String.format("%.2f", money), "Y"));
                userDivide = null;
            }

            payment = PaymentUtil
                    .executePayment(adaPayConfig, money, orderNO, openId, JSON.toJSONString(list), null, remark, account.getName());

            Double serviceFee = getServiceFee(list, userDivide);

            List<UserAdaPayLog> logs = new ArrayList<>();
            /**记录分账详细*/
            for (DivMembers divMembers : list) {
                UserAdaPayLog userAdaPayLog = new UserAdaPayLog();
                userAdaPayLog.setUserNO(divMembers.getMember_id());
                userAdaPayLog.setAccountId(adAccountId);
                userAdaPayLog.setBrandId(adaPayConfig.getAccountId());
                userAdaPayLog.setAddTime(new Date());
                userAdaPayLog.setMoney(
                        DoubleUtil.parseDouble(Double.parseDouble(divMembers.getAmount()) * 100).intValue());
                userAdaPayLog.setOrderNO(orderNO);
                userAdaPayLog.setBuyOrderNO(buyOrderNO);
                userAdaPayLog.setBuyOrderType(rechargeType);
                userAdaPayLog.setPaymentId(payment.get("id").toString());
                userAdaPayLog.setFee(0);
                userAdaPayLog.setMainUser(0);
                userAdaPayLog.setRechargeMoney((DoubleUtil.parseDouble(money * 100)).intValue());
                userAdaPayLog.setServiceFee((serviceFee).intValue());
                userAdaPayLog.setType(AdaPayConstant.ADAPAY_TYPE_USER);
                if (userDivide != null && userDivide.getUserNO().equals(divMembers.getMember_id())) {
                    userAdaPayLog.setType(AdaPayConstant.ADAPAY_TYPE_SERVICE);
                }
                if (divides.isEmpty()) {
                    userAdaPayLog.setProportion(1.0);
                    userAdaPayLog.setMainUser(1);
                } else {
                    if (money.equals(Double.valueOf(divMembers.getAmount()))) {
                        userAdaPayLog.setProportion(1.0);
                        userAdaPayLog.setMainUser(1);
                    } else {
                        userAdaPayLog.setProportion(userMap.get(divMembers.getMember_id()).getProportion());
                        /**记录主用户信息*/
                        if (userMap.get(divMembers.getMember_id()).getMainUser() == 1) {
                            userAdaPayLog.setMainUser(1);
                        }
                    }
                }
                userAdaPayLog.setConfirmId(payment.get("id").toString());
                logs.add(userAdaPayLog);
            }
            //4.0.6 由缓存 迁移 到 数据库临时表 (兼容 灰度小程序充值 - 回调线上 的测试情况)
            redisService.add(RedisConstant.ADAPAY_PAY_DETAIL + orderNO, JSON.toJSONString(logs), 5 * 60);
            // 分账信息存临时表
            userAdaPayLogTempService.batchInsert(logs);

        }
        else {
            payment = PaymentUtil.executePayment(adaPayConfig, money, orderNO, openId, null, "delay", remark, account.getName());
        }


        return payment;
    }


    /**
     * 获取押金分账账号
     *
     * @param accountId 品牌id
     * @return
     */
    @Override
    public String getDepositAccount(Integer accountId) {
        BrandRemoteConfig brandRemoteConfigDB = cacheService.getBrandRemoteConfig(accountId,
                BrandConstant.ADAPAY_CASH_DEPOSIT);
        if (brandRemoteConfigDB != null) {
            return brandRemoteConfigDB.getParamKV().substring(brandRemoteConfigDB.getParamKV().indexOf("=") + 1);
        } else {
            return null;
        }
    }

    /**
     * 获取服务费账号
     *
     * @param accountId 品牌id
     * @return
     */
    public UserDivide getHandelFee(Integer accountId) {
        UserDivide userDivide = new UserDivide();
        BrandRemoteConfig brandRemoteConfigDB = cacheService.getBrandRemoteConfig(accountId,
                BrandConstant.ADAPAY_CASH_FUWU_FEE);
        if (brandRemoteConfigDB != null) {
            /**参数类型为account=TBIT;fee=3(代表分账账号为TBIT,服务费比例为3%)*/
            String[] strings = brandRemoteConfigDB.getParamKV().split(";");
            userDivide.setMainUser(0);
            userDivide.setUserNO(strings[0].substring(strings[0].indexOf("=") + 1));
            userDivide.setProportion(Double.parseDouble(strings[1].substring(strings[1].indexOf("=") + 1)) / 100);
            return userDivide;
        } else {
            return null;
        }
    }

    /**
     * 添加分账日志
     *
     * @param orderNO
     * @param accountId
     * @param userId
     * @param money
     * @param type
     */
    public void addAdaPayLog(Integer model, String orderNO, Integer accountId, Integer userId, Double money, Integer type, Integer payChannel, Integer brandId) {
        //兜底处理，区域id和品牌id一致时，为未知区域（-1）
        accountId = accountId.equals(brandId) ? -1 : accountId;
        AdaPayLog adaPayLog = new AdaPayLog();
        adaPayLog.setOrderNO(orderNO);
        adaPayLog.setAccountId(accountId);
        adaPayLog.setUserId(userId);
        adaPayLog.setBrandId(brandId);
        adaPayLog.setMoney(money * 100);
        adaPayLog.setAddTime(new Date());
        adaPayLog.setState(AdaPayConstant.ADAPAY_LOG_DEFAULT);
        adaPayLog.setType(type);
        adaPayLog.setPayChannel(payChannel);
        adaPayLogService.add(adaPayLog);
        redisService.add(RedisConstant.ADAPAY_PAY_MODEL + orderNO, String.valueOf(model), 60);
    }

}
